线段树区间维护hdu3397
来源:互联网 发布:淘宝的销量多久清零 编辑:程序博客网 时间:2024/05/16 23:52
这个题维护的东西有点多,写恶心了,没调出来,过两天接着看
7.7样例终于过了,可还是wa。。。
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=100010;int n,m,a[maxn];struct IntervalTree{ int sum1[maxn<<3],cnt0[maxn<<3],cnt1[maxn<<3]; int r0[maxn<<3],r1[maxn<<3],l0[maxn<<3],l1[maxn<<3]; int setv[maxn<<3],XOR[maxn<<3]; void maintainXOR(int o,int l,int r) { sum1[o]=r-l+1-sum1[o]; swap(r0[o],r1[o]); swap(l0[o],l1[o]); swap(cnt0[o],cnt1[o]); } void maintain(int o,int l,int r) { if(setv[o]==0) { l0[o]=r0[o]=r-l+1; sum1[o]=l1[o]=r1[o]=0; cnt1[o]=0,cnt0[o]=r-l+1; } else if(setv[o]==1) { l0[o]=r0[o]=0; l1[o]=r1[o]=r-l+1; sum1[o]=cnt1[o]=r-l+1; cnt0[o]=0; } } void build(int o,int l,int r) { sum1[o]=r0[o]=r1[o]=l0[o]=l1[o]=cnt0[o]=cnt1[o]=0; setv[o]=-1,XOR[o]=0,cnt1[o]=cnt0[o]=0; if(l==r) { if(a[l]==1) { sum1[o]=cnt1[o]=1; r1[o]=l1[o]=1; cnt0[o]=0; r0[o]=l0[o]=0; } else { sum1[o]=cnt1[o]=0; r1[o]=l1[o]=0; cnt0[o]=1; r0[o]=l0[o]=1; } return; } int mid=(l+r)>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); pushup(o,l,r); } void pushdown(int o,int l,int r) { if(r<=l)return; if(setv[o]!=-1) { setv[o<<1]=setv[o<<1|1]=setv[o]; XOR[o<<1]=XOR[o<<1|1]=0; int mid=(l+r)>>1; maintain(o<<1,l,mid); maintain(o<<1|1,mid+1,r); setv[o]=-1; } if(XOR[o]) { XOR[o<<1]^=1; XOR[o<<1|1]^=1; XOR[o]=0; int mid=(l+r)>>1; maintainXOR(o<<1,l,mid); maintainXOR(o<<1|1,mid+1,r); } } void pushup(int o,int l,int r) { if(r<=l)return; l0[o]=l0[o<<1],l1[o]=l1[o<<1]; r0[o]=r0[o<<1|1],r1[o]=r1[o<<1|1]; cnt0[o]=max(cnt0[o<<1],cnt0[o<<1|1]); cnt1[o]=max(cnt1[o<<1],cnt1[o<<1|1]); cnt0[o]=max(cnt0[o],r0[o<<1]+l0[o<<1|1]); cnt1[o]=max(cnt1[o],r1[o<<1]+l1[o<<1|1]); int mid=(l+r)>>1; if(l0[o]==mid-l+1)l0[o]+=l0[o<<1|1]; if(l1[o]==mid-l+1)l1[o]+=l1[o<<1|1]; if(r0[o]==r-mid)r0[o]+=r0[o<<1]; if(r1[o]==r-mid)r1[o]+=r1[o<<1]; sum1[o]=sum1[o<<1]+sum1[o<<1|1]; } void update(int o,int l,int r,int q1,int q2,int op) { pushdown(o,l,r); if(q1<=l&&r<=q2) { if(op==2){XOR[o]=1;maintainXOR(o,l,r);} else {setv[o]=op;maintain(o,l,r);} return; } int mid=(l+r)>>1; if(q1<=mid)update(o<<1,l,mid,q1,q2,op);//else maintain(o<<1,l,mid); if(q2>mid)update(o<<1|1,mid+1,r,q1,q2,op);//else maintain(o<<1|1,mid+1,r); pushup(o,l,r); } int query(int o,int l,int r,int q1,int q2,int op) { pushdown(o,l,r); if(q1<=l&&r<=q2) { if(op==3)return sum1[o]; if(op==4)return cnt1[o]; } int mid=(l+r)>>1; int x=0,y=0; if(q1<=mid)x=query(o<<1,l,mid,q1,q2,op); if(q2>mid)y=query(o<<1|1,mid+1,r,q1,q2,op); if(op==3)return x+y; if(q1<=mid&&q2>mid) { x=max(x,y); y=min(mid-q1+1,r1[o<<1])+min(q2-mid,l1[o<<1|1]); x=max(x,y); } return x; }}tree;int main(){ freopen("in.txt","r",stdin); int T,x,y,op; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]); tree.build(1,1,n); while(m--) { scanf("%d%d%d",&op,&x,&y); x++,y++; if(op<=2)tree.update(1,1,n,x,y,op); else printf("%d\n",tree.query(1,1,n,x,y,op)); } } return 0;}
下面是别人的代码:
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define lson u<<1#define rson u<<1|1#define MAXN 100010int dat[MAXN];struct Node {int lef,rig;int lsum,rsum,msum;//左端最长连续1,右端最长连续1,区间最长连续1int lz,rz,mz;//左端最长连续0,右端最长连续0,区间最长连续0int sum;//区间1的个数int COVER,XOR;}T[MAXN<<2];void makeXOR(int u){//翻转操作swap(T[u].lsum,T[u].lz);swap(T[u].rsum,T[u].rz);swap(T[u].msum,T[u].mz);T[u].sum=T[u].rig-T[u].lef+1-T[u].sum;}void PushUp(int u){if(T[u].lef==T[u].rig)return;int len=T[u].rig-T[u].lef+1;T[u].lsum=T[lson].lsum;T[u].rsum=T[rson].rsum;if(T[u].lsum==(len+1)>>1)T[u].lsum+=T[rson].lsum;if(T[u].rsum==len>>1)T[u].rsum+=T[lson].rsum;T[u].msum=max(T[lson].msum,T[rson].msum);T[u].msum=max(T[u].msum,T[lson].rsum+T[rson].lsum);T[u].lz=T[lson].lz;T[u].rz=T[rson].rz;if(T[u].lz==(len+1)>>1)T[u].lz+=T[rson].lz;if(T[u].rz==len>>1)T[u].rz+=T[lson].rz;T[u].mz=max(T[lson].mz,T[rson].mz);T[u].mz=max(T[u].mz,T[lson].rz+T[rson].lz);T[u].sum=T[lson].sum+T[rson].sum;}void PushDown(int u){if(T[u].lef==T[u].rig)return;if(T[u].COVER!=-1){int len=T[u].rig-T[u].lef+1;T[lson].COVER=T[rson].COVER=T[u].COVER;T[lson].XOR=T[rson].XOR=0;T[lson].lsum=T[lson].rsum=T[lson].msum=T[u].COVER?(len+1)>>1:0;T[lson].lz=T[lson].rz=T[lson].mz=T[u].COVER?0:(len+1)>>1;T[lson].sum=T[u].COVER?(len+1)>>1:0;T[rson].lsum=T[rson].rsum=T[rson].msum=T[u].COVER?len>>1:0;T[rson].lz=T[rson].rz=T[rson].mz=T[u].COVER?0:len>>1;T[rson].sum=T[u].COVER?len>>1:0;T[u].COVER=-1;}if(T[u].XOR){T[u].XOR=0;T[lson].XOR^=1;T[rson].XOR^=1;makeXOR(lson);makeXOR(rson);}}void Build(int u,int l,int r){T[u].lef=l;T[u].rig=r;T[u].COVER=-1;T[u].XOR=0;if(l==r){T[u].lsum=T[u].rsum=T[u].msum=(dat[l]==1);T[u].lz=T[u].rz=T[u].mz=(dat[l]==0);T[u].sum=dat[l];T[u].COVER=dat[l];return;}int mid=(l+r)>>1;Build(lson,l,mid);Build(rson,mid+1,r);PushUp(u);}void Update(int u,int l,int r,int op){PushDown(u);//这里应该先pushdownif(l<=T[u].lef&&T[u].rig<=r){if(op<2){//覆盖操作int len=T[u].rig-T[u].lef+1;T[u].COVER=op;T[u].lsum=T[u].rsum=T[u].msum=op?len:0;T[u].lz=T[u].rz=T[u].mz=op?0:len;T[u].sum=op?len:0;}else {T[u].XOR=1;makeXOR(u);}}else {if(l<=T[lson].rig)Update(lson,l,r,op);if(r>=T[rson].lef)Update(rson,l,r,op);PushUp(u);}}int Query(int u,int l,int r,int op){PushDown(u);//应该先 pushdown,以防错误if(l<=T[u].lef&&T[u].rig<=r){if(op==3)return T[u].sum;else return T[u].msum;}else {if(r<=T[lson].rig)return Query(lson,l,r,op);if(l>=T[rson].lef)return Query(rson,l,r,op);if(op==3) return Query(lson,l,T[lson].rig,op)+Query(rson,T[rson].lef,r,op);int ret=min(T[lson].rsum,T[lson].rig-l+1)+min(T[rson].lsum,r-T[rson].lef+1);int ans=max(Query(lson,l,T[lson].rig,op),Query(rson,T[rson].lef,r,op));return max(ans,ret);}}int main(){int t;scanf("%d",&t);while(t--){int n,m;int cmd,a,b;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",dat+i);Build(1,1,n);while(m--){scanf("%d%d%d",&cmd,&a,&b);a++,b++;if(cmd<3)Update(1,a,b,cmd);else printf("%d\n",Query(1,a,b,cmd));}}return 0;}
0 0
- 线段树区间维护hdu3397
- hdu3397 Sequence operation 线段树区间合并
- HDU3397:Sequence operation(线段树区间合并)
- HDU3397 线段树 区间合并 双标记
- hdu3397(线段树区间合并)
- HDU3397 Sequence operation(线段树的区间合并)
- hdu3397 线段树综合
- hdu3397 线段树
- HDU3397 Sequence operation 区间修改,区间异或,区间合并,线段树经典题
- 线段树区间维护upcoj
- 线段树区间维护hdu3308
- 线段树区间维护cf46D
- POJ3468 线段树区间维护
- hdu3397 Sequence operation 线段树区间更新&&bzoj1858: [Scoi2010]序列操作
- hdu1754线段树维护区间最大值
- 线段树维护区间最大值hdu1754
- poj 3468 线段树区间更新维护
- hdu_5726_GCD(线段树维护区间+预处理)
- java二进制转换
- c字符串转整数
- The Settlers of Catan
- 04-HibernateUtil完整版,HQL查询入门
- 文件操作函数fprintf
- 线段树区间维护hdu3397
- 设计模式之装饰模式
- Java虚拟机运行时数据区域
- HDU-1255-覆盖的面积(线段树)
- hdu 4770 Lights Against Dudely(回溯)
- 算法导论——lec 09 中位数和顺序统计学
- How to turn Vim into a full-fledged IDE
- 第一次写博客
- 【剑指offer】Q19:二叉树的镜像