hdu 3397 线段树成段更新

来源:互联网 发布:康宏爱飞 知乎 编辑:程序博客网 时间:2024/06/03 10:33

题目不难但是很复杂,写的线段树比较繁琐。

线段树的成段更新要使用标记。首先三种操作对应三种标记:0表示没有需要处理的延迟操作,1表示需要全部赋值成1,-1表示需要全部赋值成0,2表示全部取反。在更新2时要注意一下,如果之前是1,变成-1;之前是-1变成1;之前是2变成0(wa了好久都是忘记考虑这种情况);之前是0变成2;

对于置换这个操作,我在树的节点中存了l0,r0,m0和rl1,r1,m1分别表示当前段从左,从右,以及总体的最大连续的0/1的数目,这样在置换的时候只要0与1的对应数据互换就好

自己犯了不少错误,更新的时候忘记更新标记,还有建树的时候最开始只在left==right的时候更新了标记。

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>struct Tree{int sum;int l1,r1,m1;int l0,r0,m0;int vis;}tree[1200005];int a[100005];int n,m,h1,h2,h3;int max(int a,int b){if(a>b)return a;else return b;}int min(int a,int b){if(a<b)return a;else return b;}void update(int left,int right,int root){int mid;mid=(left+right)/2;if(tree[root].vis==1){tree[root<<1].l1=tree[root<<1].m1=tree[root<<1].r1=tree[root<<1].sum=mid-left+1;tree[root<<1].l0=tree[root<<1].r0=tree[root<<1].m0=0;tree[root<<1].vis=1;tree[root<<1|1].l1=tree[root<<1|1].m1=tree[root<<1|1].r1=tree[root<<1|1].sum=right-(mid+1)+1;tree[root<<1|1].l0=tree[root<<1|1].r0=tree[root<<1|1].m0=0;tree[root<<1|1].vis=1;}else if(tree[root].vis==-1){tree[root<<1].l1=tree[root<<1].m1=tree[root<<1].r1=tree[root<<1].sum=0;tree[root<<1].l0=tree[root<<1].r0=tree[root<<1].m0=mid-left+1;tree[root<<1].vis=-1;tree[root<<1|1].l1=tree[root<<1|1].m1=tree[root<<1|1].r1=tree[root<<1|1].sum=0;tree[root<<1|1].l0=tree[root<<1|1].r0=tree[root<<1|1].m0=right-(mid+1)+1;tree[root<<1|1].vis=-1;}else if(tree[root].vis==2){tree[root<<1].sum=mid-left+1-tree[root<<1].sum;h1=tree[root<<1].l0;h2=tree[root<<1].r0;h3=tree[root<<1].m0;tree[root<<1].l0=tree[root<<1].l1;tree[root<<1].r0=tree[root<<1].r1;tree[root<<1].m0=tree[root<<1].m1;tree[root<<1].l1=h1;tree[root<<1].r1=h2;tree[root<<1].m1=h3;if(tree[root<<1].vis==-1)tree[root<<1].vis=1;else if(tree[root<<1].vis==1)tree[root<<1].vis=-1;else if(tree[root<<1].vis==2)tree[root<<1].vis=0;elsetree[root<<1].vis=2;tree[root<<1|1].sum=right-(mid+1)+1-tree[root<<1|1].sum;h1=tree[root<<1|1].l0;h2=tree[root<<1|1].r0;h3=tree[root<<1|1].m0;tree[root<<1|1].l0=tree[root<<1|1].l1;tree[root<<1|1].r0=tree[root<<1|1].r1;tree[root<<1|1].m0=tree[root<<1|1].m1;tree[root<<1|1].l1=h1;tree[root<<1|1].r1=h2;tree[root<<1|1].m1=h3;if(tree[root<<1|1].vis==-1)tree[root<<1|1].vis=1;else if(tree[root<<1|1].vis==1)tree[root<<1|1].vis=-1;else if(tree[root<<1|1].vis==2)tree[root<<1|1].vis=0;elsetree[root<<1|1].vis=2;}tree[root].vis=0;}void build(int left,int right,int root){if(left==right){tree[root].l1=tree[root].m1=tree[root].r1=tree[root].sum=a[left];if(a[left])tree[root].l0=tree[root].m0=tree[root].r0=0;elsetree[root].l0=tree[root].m0=tree[root].r0=1;tree[root].vis=tree[root<<1].vis=tree[root<<1|1].vis=0;return ;}int mid;mid=(left+right)/2;build(left,mid,root<<1);build(mid+1,right,root<<1|1);tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;if(tree[root<<1].l1==mid-left+1)tree[root].l1=tree[root<<1].l1+tree[root<<1|1].l1;elsetree[root].l1=tree[root<<1].l1;if(tree[root<<1|1].r1==right-(mid+1)+1)tree[root].r1=tree[root<<1|1].r1+tree[root<<1].r1;elsetree[root].r1=tree[root<<1|1].r1;tree[root].m1=max(max(tree[root<<1].m1,tree[root<<1|1].m1),tree[root<<1].r1+tree[root<<1|1].l1);if(tree[root<<1].l0==mid-left+1)tree[root].l0=tree[root<<1].l0+tree[root<<1|1].l0;elsetree[root].l0=tree[root<<1].l0;if(tree[root<<1|1].r0==right-(mid+1)+1)tree[root].r0=tree[root<<1|1].r0+tree[root<<1].r0;elsetree[root].r0=tree[root<<1|1].r0;tree[root].m0=max(max(tree[root<<1].m0,tree[root<<1|1].m0),tree[root<<1].r0+tree[root<<1|1].l0);tree[root].vis=tree[root<<1].vis=tree[root<<1|1].vis=0;}void xiao(int left,int right,int root,int l,int r){if(left==l && right==r){tree[root].l1=tree[root].m1=tree[root].r1=tree[root].sum=0;tree[root].l0=tree[root].m0=tree[root].r0=right-left+1;tree[root].vis=-1;return ;}int mid;mid=(left+right)/2;update(left,right,root);if(r<=mid)xiao(left,mid,root<<1,l,r);else if(l>=mid+1)xiao(mid+1,right,root<<1|1,l,r);else{xiao(left,mid,root<<1,l,mid);xiao(mid+1,right,root<<1|1,mid+1,r);}tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;if(tree[root<<1].l1==mid-left+1)tree[root].l1=tree[root<<1].l1+tree[root<<1|1].l1;elsetree[root].l1=tree[root<<1].l1;if(tree[root<<1|1].r1==right-(mid+1)+1)tree[root].r1=tree[root<<1|1].r1+tree[root<<1].r1;elsetree[root].r1=tree[root<<1|1].r1;tree[root].m1=max(max(tree[root<<1].m1,tree[root<<1|1].m1),tree[root<<1].r1+tree[root<<1|1].l1);if(tree[root<<1].l0==mid-left+1)tree[root].l0=tree[root<<1].l0+tree[root<<1|1].l0;elsetree[root].l0=tree[root<<1].l0;if(tree[root<<1|1].r0==right-(mid+1)+1)tree[root].r0=tree[root<<1|1].r0+tree[root<<1].r0;elsetree[root].r0=tree[root<<1|1].r0;tree[root].m0=max(max(tree[root<<1].m0,tree[root<<1|1].m0),tree[root<<1].r0+tree[root<<1|1].l0);}void man(int left,int right,int root,int l,int r){if(left==l && right==r){tree[root].l1=tree[root].m1=tree[root].r1=tree[root].sum=right-left+1;tree[root].l0=tree[root].r0=tree[root].m0=0;tree[root].vis=1;return ;}int mid;mid=(left+right)/2;update(left,right,root);if(r<=mid)man(left,mid,root<<1,l,r);else if(l>=mid+1)man(mid+1,right,root<<1|1,l,r);else{man(left,mid,root<<1,l,mid);man(mid+1,right,root<<1|1,mid+1,r);}tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;if(tree[root<<1].l1==mid-left+1)tree[root].l1=tree[root<<1].l1+tree[root<<1|1].l1;elsetree[root].l1=tree[root<<1].l1;if(tree[root<<1|1].r1==right-(mid+1)+1)tree[root].r1=tree[root<<1|1].r1+tree[root<<1].r1;elsetree[root].r1=tree[root<<1|1].r1;tree[root].m1=max(max(tree[root<<1].m1,tree[root<<1|1].m1),tree[root<<1].r1+tree[root<<1|1].l1);if(tree[root<<1].l0==mid-left+1)tree[root].l0=tree[root<<1].l0+tree[root<<1|1].l0;elsetree[root].l0=tree[root<<1].l0;if(tree[root<<1|1].r0==right-(mid+1)+1)tree[root].r0=tree[root<<1|1].r0+tree[root<<1].r0;elsetree[root].r0=tree[root<<1|1].r0;tree[root].m0=max(max(tree[root<<1].m0,tree[root<<1|1].m0),tree[root<<1].r0+tree[root<<1|1].l0);}void zhi(int left,int right,int root,int l,int r){if(left==l && right==r){tree[root].sum=right-left+1-tree[root].sum;h1=tree[root].l0;h2=tree[root].r0;h3=tree[root].m0;tree[root].l0=tree[root].l1;tree[root].r0=tree[root].r1;tree[root].m0=tree[root].m1;tree[root].l1=h1;tree[root].r1=h2;tree[root].m1=h3;if(tree[root].vis==-1)tree[root].vis=1;else if(tree[root].vis==1)tree[root].vis=-1;else if(tree[root].vis==2)tree[root].vis=0;elsetree[root].vis=2;return ;}int mid;mid=(left+right)/2;update(left,right,root);if(r<=mid)zhi(left,mid,root<<1,l,r);else if(l>=mid+1)zhi(mid+1,right,root<<1|1,l,r);else{zhi(left,mid,root<<1,l,mid);zhi(mid+1,right,root<<1|1,mid+1,r);}tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;if(tree[root<<1].l1==mid-left+1)tree[root].l1=tree[root<<1].l1+tree[root<<1|1].l1;elsetree[root].l1=tree[root<<1].l1;if(tree[root<<1|1].r1==right-(mid+1)+1)tree[root].r1=tree[root<<1|1].r1+tree[root<<1].r1;elsetree[root].r1=tree[root<<1|1].r1;tree[root].m1=max(max(tree[root<<1].m1,tree[root<<1|1].m1),tree[root<<1].r1+tree[root<<1|1].l1);if(tree[root<<1].l0==mid-left+1)tree[root].l0=tree[root<<1].l0+tree[root<<1|1].l0;elsetree[root].l0=tree[root<<1].l0;if(tree[root<<1|1].r0==right-(mid+1)+1)tree[root].r0=tree[root<<1|1].r0+tree[root<<1].r0;elsetree[root].r0=tree[root<<1|1].r0;tree[root].m0=max(max(tree[root<<1].m0,tree[root<<1|1].m0),tree[root<<1].r0+tree[root<<1|1].l0);}int he(int left,int right,int root,int l,int r){if(left==l && right==r)return tree[root].sum;int mid;mid=(left+right)/2;update(left,right,root);if(r<=mid)return he(left,mid,root<<1,l,r);else if(l>=mid+1)return he(mid+1,right,root<<1|1,l,r);elsereturn he(left,mid,root<<1,l,mid)+he(mid+1,right,root<<1|1,mid+1,r);}int lian(int left,int right,int root,int l,int r){if(left==l && right==r)return tree[root].m1;int mid;mid=(left+right)/2;update(left,right,root);if(r<=mid)return lian(left,mid,root<<1,l,r);else if(l>=mid+1)return lian(mid+1,right,root<<1|1,l,r);else{int ta,tb,tc;ta=lian(left,mid,root<<1,l,mid);tb=lian(mid+1,right,root<<1|1,mid+1,r);tc= min(tree[root<<1].r1,mid-l+1)+min(tree[root<<1|1].l1,r-(mid+1)+1);return max(tc,max(ta,tb));}}int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);int i,j;for(i=1;i<=n;i++)scanf("%d",&a[i]);build(1,n,1);int ta,tb,tc,ans;while(m--){scanf("%d%d%d",&tc,&ta,&tb);ta++;tb++;if(tc==0)xiao(1,n,1,ta,tb);else if(tc==1)man(1,n,1,ta,tb);else if(tc==2)zhi(1,n,1,ta,tb);else if(tc==3){ans=he(1,n,1,ta,tb);printf("%d\n",ans);}else{ans=lian(1,n,1,ta,tb);printf("%d\n",ans);}}}return 0;}



附个数据

3

10 20
0 0 0 0 0 0 0 0 0 0
3 1 8
0 3 8
3 5 8
2 4 4
1 1 1
3 2 8
4 5 6
1 6 7
1 5 7
1 5 9
1 3 5
0 1 1
0 6 7
1 2 4
1 4 5
4 8 8
1 8 9
0 1 8
0 1 9
3 2 2
10 20
0 0 0 0 0 0 0 0 0 0
4 0 1
3 1 1
4 0 2
0 3 8
3 3 3
3 2 4
4 7 8
0 6 8
3 1 8
3 0 2
3 0 5
4 6 6
1 2 4
3 3 4
4 1 6
3 3 5
4 7 9
0 6 8
1 0 8
1 0 4
10 20
0 0 0 0 0 0 0 0 0 0
2 6 8
4 0 6
0 4 9
2 5 9
3 2 6
1 0 4
1 3 5
0 8 9
2 1 6
0 9 9
4 3 6
2 7 7
1 2 7
3 2 6
2 4 4
4 2 6
4 4 9
1 1 7
2 6 7
3 0 9


0
0
1
0
1
0


0
0
0
0
0
0
0
0
0
0
2
3
2
0


1
2
0
5
2
3
6


0 0
原创粉丝点击