题解 P3130 【[USACO15DEC]计数haybalesCounting Haybales】

流逝丶

2019-11-11 21:19:09

Solution

## 线段树 这题标签错了吧。明明是线段树裸题啊 维护区间和,区间最小值,区间加修改,基本操作嘛,注意开longlong 一遍过,直接上代码吧。。 ```cpp #include<iostream> #include<cstdio> #define lson k<<1,l,mid #define rson k<<1|1,mid+1,r #define ls k<<1 #define rs k<<1|1 #define mid ((l+r)>>1) #define LL long long using namespace std; const int N=200005; int n,q; LL tr[N<<2],laz[N<<2],mi[N<<2]; inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();} return w*s; } inline void update(int k){ tr[k]=tr[ls]+tr[rs]; mi[k]=min(mi[ls],mi[rs]); } inline void down(int k,int l,int r){ laz[ls]+=laz[k];laz[rs]+=laz[k]; tr[ls]+=laz[k]*(mid-l+1);mi[ls]+=laz[k]; tr[rs]+=laz[k]*(r-mid);mi[rs]+=laz[k]; laz[k]=0; } void build(int k,int l,int r){ if(l==r){ tr[k]=mi[k]=read(); return ; } build(lson);build(rson); update(k); } void change(int k,int l,int r,int x,int y,int z){ if(l==x&&y==r){ tr[k]+=(LL)z*(r-l+1); mi[k]+=z; laz[k]+=z; return ; } if(laz[k])down(k,l,r); if(y<=mid)change(lson,x,y,z); else if(x>mid)change(rson,x,y,z); else change(lson,x,mid,z),change(rson,mid+1,y,z); update(k); } LL ask(int k,int l,int r,int x,int y){ if(l==x&&y==r){ return tr[k]; } if(laz[k])down(k,l,r); if(y<=mid)return ask(lson,x,y); else if(x>mid)return ask(rson,x,y); else return ask(lson,x,mid)+ask(rson,mid+1,y); } LL query(int k,int l,int r,int x,int y){ if(l==x&&y==r){ return mi[k]; } if(laz[k])down(k,l,r); if(y<=mid)return query(lson,x,y); else if(x>mid)return query(rson,x,y); else return min(query(lson,x,mid),query(rson,mid+1,y)); } int main(){ n=read();q=read(); build(1,1,n); char ch[5]; int x,y,z; while(q--){ scanf("%s",ch+1); x=read();y=read(); if(ch[1]=='P'){z=read();change(1,1,n,x,y,z);} else if(ch[1]=='M'){printf("%lld\n",query(1,1,n,x,y));} else if(ch[1]=='S'){printf("%lld\n",ask(1,1,n,x,y));} } return 0; } ```