不败丶流逝 的博客

不败丶流逝 的博客

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

posted on 2019-11-11 21:19:09 | under 题解 |

线段树

这题标签错了吧。明明是线段树裸题啊

维护区间和,区间最小值,区间加修改,基本操作嘛,注意开longlong

一遍过,直接上代码吧。。

#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;
}