SPOJ7299. Multiples of 3

来源:互联网 发布:矩阵奇异值分解过程 编辑:程序博客网 时间:2024/06/05 08:45
这道题主要要注意在成段更新这种类型的题目中,询问也要更新叶子结点的信息。
#include<stdio.h>#include<string.h>int n,m,setv[4000000][4],ans;void pushup(int rt){int lt=rt<<1;int t=(rt<<1)|1;setv[rt][1]=setv[lt][1]+setv[t][1];setv[rt][2]=setv[lt][2]+setv[t][2];setv[rt][0]=setv[lt][0]+setv[t][0];}void build(int rt,int l,int r){if(l==r){setv[rt][0]=1;}else{int mid=(l+r)>>1;build(rt*2,l,mid);build(rt*2+1,mid+1,r);pushup(rt);}}void pushdown(int rt,int l,int r){int x=rt<<1,y=x|1;if(setv[rt][3]==1){setv[x][3]=(setv[x][3]+setv[rt][3])%3;setv[y][3]=(setv[y][3]+setv[rt][3])%3;int temp=setv[x][1];setv[x][1]=setv[x][0];setv[x][0]=setv[x][2];setv[x][2]=temp;    temp=setv[y][1];setv[y][1]=setv[y][0];setv[y][0]=setv[y][2];setv[y][2]=temp;setv[rt][3]=0;}else if(setv[rt][3]==2){setv[x][3]=(setv[x][3]+setv[rt][3])%3;setv[y][3]=(setv[y][3]+setv[rt][3])%3;int temp=setv[x][2];setv[x][2]=setv[x][0];setv[x][0]=setv[x][1];setv[x][1]=temp;temp=setv[y][2];setv[y][2]=setv[y][0];setv[y][0]=setv[y][1];setv[y][1]=temp;setv[rt][3]=0;}}void update(int rt,int l,int r,int a,int b){if(a<=l&&b>=r){setv[rt][3]=(setv[rt][3]+1)%3;int temp=setv[rt][1];setv[rt][1]=setv[rt][0];setv[rt][0]=setv[rt][2];setv[rt][2]=temp;return;}int mid=(l+r)>>1;pushdown(rt,l,r);if(a<=mid)update(rt*2,l,mid,a,b);if(b>mid)update(rt*2+1,mid+1,r,a,b);pushup(rt);}int query(int rt,int l,int r,int a,int b){if(a<=l&&r<=b){return setv[rt][0];}pushdown(rt,l,r);//记得要更新叶子结点。int mid=(l+r)/2;if(b<=mid)return query(rt*2,l,mid,a,b);else if(a>mid)return query(rt*2+1,mid+1,r,a,b);else return query(rt*2,l,mid,a,b)+query(rt*2+1,mid+1,r,a,b);}int main(){freopen("t.txt","r",stdin);while(~scanf("%d%d",&n,&m)){build(1,1,n);int i,q,a,b;for(i=0;i<m;i++){scanf("%d%d%d",&q,&a,&b);a++;b++;if(q==0)update(1,1,n,a,b);else{ans=query(1,1,n,a,b);printf("%d\n",ans);}}}return 0;}

0 0
原创粉丝点击