hdu 3397 Sequence operation(区间合并)
来源:互联网 发布:linux exec fork 编辑:程序博客网 时间:2024/05/16 04:53
题意:首先t表示有几组数据,然后n,m表示有n个数,m组操作,接着给你n个0或1的数字,,最后是操作0 a b表示把区间[a,b]里的数都变成0,1 a b把区间[a,b]里的数都变成1,2 a b表示把区间[a,b]里的1变成0,0变成1,3 a b表示[a,b]输出1的数目,4 a b表示输出最长的连续的1的数目。
区间合并的问题,因为最长的可能的除了可能出现在端点,还有可能出现在区间合并时,两边的连续的加起来。除了这个之外,还要注意,我们设置两个延迟标记,一个用来标记操作0、1,一个用来标记操作2,如果我们在进行操作0、1的更新的时候,如果有遇到操作2的标记,那么没必要往下更新标记2(因为会把操作2覆盖了),但是如果是进行操作2的更新,遇到操作0、1的更新,我们要往下更新。
因为有涉及到将0变成1,将1变成0的操作,所以我们除了记录端点处连续的1的长度,区间内1的数目,区间内最长的连续的1的数目之外,我们还要记录关于0相同的信息,这样,当有置反操作的时候,我们简单地交换对应的0和1的信息就可以了。
/*代码风格更新后 */#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define MID(a,b) (a+((b-a)>>1))const int N=100005;struct node{int lft,rht;int lmx_0,rmx_0,mx_0,sum_0;int lmx_1,rmx_1,mx_1,sum_1;int flag_set,flag_rev;int len(){return rht-lft+1;}int mid(){return MID(lft,rht);}void set_0(int a){ lmx_0=rmx_0=mx_0=sum_0=a; }void set_1(int a){ lmx_1=rmx_1=mx_1=sum_1=a; }void init(){set_0(0); set_1(0);flag_rev=0; flag_set=-1;}void fun(int valu){if(valu==0){flag_set=0; flag_rev=0;set_0(len()); set_1(0);}else if(valu==1){flag_set=1; flag_rev=0;set_0(0); set_1(len());}else {swap(lmx_0,lmx_1); swap(rmx_0,rmx_1);swap(mx_0,mx_1);swap(sum_0,sum_1);flag_rev^=1;}}};int y[N],n,m;struct Segtree{node tree[N*4];void down(int ind){if(tree[ind].flag_set!=-1){tree[LL(ind)].fun(tree[ind].flag_set);tree[RR(ind)].fun(tree[ind].flag_set);tree[ind].flag_set=-1;}if(tree[ind].flag_rev){tree[LL(ind)].fun(2);tree[RR(ind)].fun(2);tree[ind].flag_rev=0;}}void up(node &a,node &b,node &c){a.lmx_0=b.lmx_0; a.rmx_0=c.rmx_0; a.lmx_1=b.lmx_1; a.rmx_1=c.rmx_1; a.sum_0=b.sum_0+c.sum_0; a.sum_1=b.sum_1+c.sum_1; a.mx_0=max(b.rmx_0+c.lmx_0,max(b.mx_0,c.mx_0)); a.mx_1=max(b.rmx_1+c.lmx_1,max(b.mx_1,c.mx_1)); if(b.len()==b.lmx_0) a.lmx_0+=c.lmx_0; if(b.len()==b.lmx_1) a.lmx_1+=c.lmx_1; if(c.len()==c.rmx_0) a.rmx_0+=b.rmx_0; if(c.len()==c.rmx_1) a.rmx_1+=b.rmx_1; }void build(int lft,int rht,int ind){tree[ind].lft=lft;tree[ind].rht=rht;tree[ind].init();if(lft==rht) {if(y[lft]==1) tree[ind].set_0(0),tree[ind].set_1(1);else tree[ind].set_0(1),tree[ind].set_1(0);}else {int mid=tree[ind].mid();build(lft,mid,LL(ind));build(mid+1,rht,RR(ind));up(tree[ind],tree[LL(ind)],tree[RR(ind)]);}}void updata(int st,int ed,int ind,int valu){int lft=tree[ind].lft,rht=tree[ind].rht;if(st<=lft&&rht<=ed) tree[ind].fun(valu);else {down(ind);int mid=tree[ind].mid();if(st<=mid) updata(st,ed,LL(ind),valu);if(ed> mid) updata(st,ed,RR(ind),valu);up(tree[ind],tree[LL(ind)],tree[RR(ind)]);}}int query(int st,int ed,int ind,int type){int lft=tree[ind].lft,rht=tree[ind].rht;if(st<=lft&&rht<=ed) {if(type==3) return tree[ind].sum_1;else return tree[ind].mx_1;}else {down(ind);int mid=tree[ind].mid(),res;if(ed<=mid) res=query(st,ed,LL(ind),type);else if(st>mid) res=query(st,ed,RR(ind),type);else {int tmp1=query(st,ed,LL(ind),type);int tmp2=query(st,ed,RR(ind),type);if(type==3) res=tmp1+tmp2;else {int tmp3=min(tree[LL(ind)].rmx_1,tree[LL(ind)].rht-st+1);int tmp4=min(tree[RR(ind)].lmx_1,ed-tree[RR(ind)].lft+1);res=max(max(tmp1,tmp2),tmp3+tmp4);}}up(tree[ind],tree[LL(ind)],tree[RR(ind)]);return res;}}}seg;int main(){int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i=0;i<n;i++) scanf("%d",&y[i]);seg.build(0,n-1,1);for(int i=0;i<m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);if(a<=2) seg.updata(b,c,1,a);else printf("%d\n",seg.query(b,c,1,a));}}return 0;}
/*代码风格更新前*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N=100005;int y[N];struct node{ int left,right,co,flag; int maxl_0,maxr_0,maxl_1,maxr_1; int sum_0,sum_1,max_1,max_0; int mid(){return left+(right-left)/2;} int dis(){return right-left+1;} void change(int a,int rev) { if(a==0) { maxl_0=maxr_0=sum_0=max_0=dis(); maxl_1=maxr_1=sum_1=max_1=0; co=a; flag=0; } else if(a==1) { maxl_0=maxr_0=sum_0=max_0=0; maxl_1=maxr_1=sum_1=max_1=dis(); co=a; flag=0; } if(rev) { swap(maxr_1,maxr_0); swap(maxl_0,maxl_1); swap(max_0,max_1); swap(sum_0,sum_1); flag^=1; } }};void unin(node &a,node &b,node &c){ a.maxl_0=b.maxl_0; a.maxr_0=c.maxr_0; a.maxl_1=b.maxl_1; a.maxr_1=c.maxr_1; a.sum_0=b.sum_0+c.sum_0; a.sum_1=b.sum_1+c.sum_1; a.max_0=max(b.maxr_0+c.maxl_0,max(b.max_0,c.max_0)); a.max_1=max(b.maxr_1+c.maxl_1,max(b.max_1,c.max_1)); if(b.dis()==b.maxl_0) a.maxl_0+=c.maxl_0; if(b.dis()==b.maxl_1) a.maxl_1+=c.maxl_1; if(c.dis()==c.maxr_0) a.maxr_0+=b.maxr_0; if(c.dis()==c.maxr_1) a.maxr_1+=b.maxr_1;}struct Segtree{ node tree[N*4]; void build(int left,int right,int r) { tree[r].left=left; tree[r].right=right; tree[r].maxl_0=tree[r].maxr_0=tree[r].maxl_1=tree[r].maxr_1=0; tree[r].sum_0=tree[r].sum_1=tree[r].max_0=tree[r].max_1=0; tree[r].flag=0; tree[r].co=-1; if(left==right) { tree[r].change(y[left],0); } else { int mid=tree[r].mid(); build(left,mid,r*2); build(mid+1,right,r*2+1); unin(tree[r],tree[r*2],tree[r*2+1]); } } void updata(int be,int end,int r,int co) { if(be<=tree[r].left&&tree[r].right<=end) { if(co==0||co==1) tree[r].change(co,0); else tree[r].change(-1,1); } else { if(tree[r].co!=-1||tree[r].flag) { tree[r*2].change(tree[r].co,tree[r].flag); tree[r*2+1].change(tree[r].co,tree[r].flag); tree[r].co=-1; tree[r].flag=0; } int mid=tree[r].mid(); if(be<=mid) updata(be,end,r*2,co); if(end>mid) updata(be,end,r*2+1,co); unin(tree[r],tree[r*2],tree[r*2+1]); } } int query(int be,int end,int r,int co) { if(be<=tree[r].left&&tree[r].right<=end) { if(co==3) return tree[r].sum_1; else return tree[r].max_1; } else { if(tree[r].co!=-1||tree[r].flag) { tree[r*2].change(tree[r].co,tree[r].flag); tree[r*2+1].change(tree[r].co,tree[r].flag); tree[r].co=-1; tree[r].flag=0; } int mid=tree[r].mid(); if(end<=mid) return query(be,end,r*2,co); else if(be>mid) return query(be,end,r*2+1,co); else { int max1=query(be,end,r*2,co); int max2=query(be,end,r*2+1,co); if(co==3) return max1+max2; int max3=min(tree[r*2].right-be+1,tree[r*2].maxr_1)+min(end-tree[r*2+1].left+1,tree[r*2+1].maxl_1); return max(max(max1,max2),max3); } } }}seg;int main(){ int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&y[i]); seg.build(0,n-1,1); for(int i=0;i<m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(a==0||a==1||a==2) seg.updata(b,c,1,a); else printf("%d\n",seg.query(b,c,1,a)); //for(int j=0;j<n;j++) printf("%d ",seg.query(j,j,1,3)); puts(""); } } return 0;}
- hdu 3397 Sequence operation(区间合并)
- HDU 3397 Sequence operation (区间合并 )
- HDU 3397 Sequence operation(区间合并)
- HDU 3397 Sequence operation(区间合并 + 区间更新)
- HDU 3397 Sequence operation 线段树(区间合并)
- HDU 3397 Sequence operation(线段树区间合并)
- HDU 3397 Sequence operation(线段树的区间合并)
- Hdu 3397 Sequence operation 区间合并+区间更新+翻转操作
- hdu 3397 Sequence operation(线段树区间覆盖,区间合并)
- HDU 3397——Sequence operation(线段树,区间染色+区间异或+区间合并)
- hdu 3397 Sequence operation(线段树,lazy,区间合并)
- 【线段树】HDU 3397 Sequence operation 区间合并
- HDU 3397 Sequence operation (线段树区间合并入门)
- HDU 3397 - Sequence operation(线段树+区间合并)
- hdu 3397 Sequence operation (线段树+区间合并+双Lazy标记)
- hdu 3379 Sequence operation(成段更新,区间合并)
- HDU 3397 Sequence operation(线段树·成段更新·区间合并·混合操作)
- HDU-3397:Sequence operation(区间更新之合集?)
- javascript计算小数保留两位小数,多位小数的方法
- crontab 各参数详解
- Apache+php+mysql+phpMyAdmin安装要点备忘
- MATLAB中FFT的使用方法
- JVM自定义参数
- hdu 3397 Sequence operation(区间合并)
- Android AVD Eclipse版快捷键
- URLRequest For JAVA
- GetParameter For Lotusscript
- Oracle 工具后台进程
- Xfce与Fluxbox
- const int * p与int *const p的详解
- 软件工程之面向过程的软件设计方法
- 关于学习,关于博客……