【Usaco2015 dec 】Counting Haybales

来源:互联网 发布:守望先锋短十字数据 编辑:程序博客网 时间:2024/05/19 21:15

题意

农夫约翰打算重修他的农场。他有 N 块土地,连续排列成一行,标号为 1…N。在每块土地上有任意数量的草堆。他可以发出三种指令:
1) 对一个连续区间的土地,每块土地增加相同数量的草堆。
2) 对一个连续区间的土地,输出其中最少的草堆数量。
3) 对一个连续区间的土地,输出草堆数量总数。

第一行两个正整数,N (1≤N≤200,000) 和 Q (1≤Q≤100,000)。
下一行是N个非负整数,最大100,000,表示每块土地上有多少个草堆。
以下Q行,每行一单个大写字母开头(M,P或S),空格后跟随两个正整数 A 和 B (1≤A≤B≤N), 或者三个正整数 A, B, 和 C (1≤A≤B≤N; 1≤C≤100,000)。当且仅当第一个字母是 P 时,是三个正整数。
当该字母是M,输出区间A…B的最小草堆数。
当该字母是P,在区间A…B,每块土地增加C堆草。
当该字母是M,输出区间A…B的草堆数之和。

每行一个数字,用于响应’M’ 或 ‘S’ 命令。

样例

SAMPLE INPUT:
4 5
3 1 2 4
M 3 4
S 1 3
P 2 3 1
M 3 4
S 1 3
SAMPLE OUTPUT:
2
6
3
8

分析

一道线段树的裸题,维护区间的最小值、和。
没什么好说的,直接套用线段树。
注意用long long

代码

#include<cstdio>#include<algorithm>#include<vector>#include<cstring>#include<iostream>#include<cmath>#include<queue>#define ll long longusing namespace std;const int inf=2000000001;const int maxn=200000+20;const int manq=100000+20;ll n,q;struct Tree{    ll y1,y2,v;    ll sumv[maxn*4];    ll minv[maxn*4];    ll addv[maxn*4];    void maintain(ll o,ll L,ll R)    {        ll lc=o*2,rc=o*2+1;        sumv[o]=minv[o]=0;        if(R>L){            sumv[o]=sumv[lc]+sumv[rc];            minv[o]=min(minv[lc],minv[rc]);        }           minv[o]+=addv[o];sumv[o]+=addv[o]*(R-L+1);    }     void update(ll o,ll L,ll R){        ll lc=o*2;        ll rc=o*2+1;        if(y1<=L&&y2>=R)          addv[o]+=v;        else{          ll M=(L+R)>>1;          if(y1<=M) update(lc,L,M);          if(y2>M) update(rc,M+1,R);        }        maintain(o,L,R);    }    ll _min,_sum;    void query(ll o,ll L,ll R,ll add){        if(y1<=L&&y2>=R){            _sum+=sumv[o]+add*(R-L+1);            _min=min(_min,minv[o]+add);        }        else{            ll M=(R+L)>>1;            if(y1<=M) query(o*2,L,M,add+addv[o]);            if(y2>M) query(o*2+1,M+1,R,add+addv[o]);        }    }}t;int main(){    //freopen("haybales.in","r",stdin);    //freopen("haybales.out","w",stdout);    cin>>n>>q;    for(ll i=1;i<=n;i++)    {      scanf("%d",&t.v);      t.y2=t.y1=i;      t.update(1,1,n);      }    char a[5];    while(q--)    {        scanf("%s",a);        if(a[0]=='M'){            t._min=inf;            scanf("%d%d",&t.y1,&t.y2);            t.query(1,1,n,0);            cout<<t._min;            printf("\n");        }        else if(a[0]=='S'){            t._sum=0;            scanf("%d%d",&t.y1,&t.y2);            t.query(1,1,n,0);            cout<<t._sum;            printf("\n");        }        else if(a[0]=='P'){            scanf("%d%d%d",&t.y1,&t.y2,&t.v);            t.update(1,1,n);        }    }     return 0; }
2 0
原创粉丝点击