首页 > 代码库 > 【POJ3468】A Simple Problem with Integers

【POJ3468】A Simple Problem with Integers

单一标记线段树。

在给定数列上建树:build时读入即可。

技术分享
 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int N=100010; 5 long long tag[N<<2],sum[N<<2],c; 6 void build(int,int,int),release(int,int,int),update(int), 7     add(int,int,int,long long),modify(int,int,int,int,int,long long); 8 long long query(int,int,int,int,int); 9 int main(){10     int x,y,n,q;11     scanf("%d %d",&n,&q);12     build(1,1,n);13     for (int i=1;i<=q;i++){14         getchar();15         char ch=getchar();16         scanf("%d %d",&x,&y);17         if (ch==C){18             scanf("%lld",&c);19             modify(1,1,n,x,y,c);20         }21         else printf("%lld\n",query(1,1,n,x,y));22     }23 }24 void build(int i,int l,int r){25     tag[i]=0;26     if (l==r){27         scanf("%lld",&sum[i]);28         return;29     }30     int mid=(l+r)>>1;31     build(i<<1,l,mid);32     build(i<<1|1,mid+1,r);33     update(i);34 }35 void update(int i){36     sum[i]=sum[i<<1]+sum[i<<1|1];37 }38 void modify(int i,int l,int r,int L,int R,long long d){39     if (L<=l&&r<=R){40         add(i,l,r,d);return;41     }42     release(i,l,r);43     int mid=(l+r)>>1;44     if (L<=mid) modify(i<<1,l,mid,L,R,d);45     if (R>mid) modify(i<<1|1,mid+1,r,L,R,d);46     update(i);47 }48 void add(int i,int l,int r,long long d){49     tag[i]+=d;50     sum[i]+=(r-l+1)*d;51 }52 void release(int i,int l,int r){53     if (tag[i]){ 54         int mid=(l+r)>>1;55         add(i<<1,l,mid,tag[i]);56         add(i<<1|1,mid+1,r,tag[i]);57         tag[i]=0;58     }59 }60 long long query(int i,int l,int r,int L,int R){61     if (L<=l&&r<=R) return sum[i];62     release(i,l,r);63     int mid=(l+r)>>1;64     long long ans=0;65     if (L<=mid) ans+=query(i<<1,l,mid,L,R);66     if (R>mid) ans+=query(i<<1|1,mid+1,r,L,R);67     return ans;68 }
STD

 

【POJ3468】A Simple Problem with Integers