BZOJ 4592 脑洞治疗仪
Posted ziliuziliu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 4592 脑洞治疗仪相关的知识,希望对你有一定的参考价值。
天啦噜我自己YY的从任意起点开始的线段树上二分居然是对的。。。。
好感动啊。
4.7k的代码只调了一个晚上好感动。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 200500 using namespace std; int n,m,sum[maxn<<2],lazy[maxn<<2],ls[maxn<<2],rs[maxn<<2],tot=0,root,l[maxn<<2],r[maxn<<2],mx[maxn<<2]; int type,l1,r1,l2,r2; struct status { int mx,l,r,len; status (int mx,int l,int r,int len):mx(mx),l(l),r(r),len(len) {} status () {} }; void build(int &now,int left,int right) { now=++tot;sum[now]=right-left+1;lazy[now]=-1; if (left==right) return; int mid=(left+right)>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); } void pushdown(int now,int left,int right) { if (lazy[now]==-1) return; lazy[ls[now]]=lazy[rs[now]]=lazy[now]; int mid=(left+right)>>1,ll=mid-left+1,rl=right-mid; sum[ls[now]]=lazy[ls[now]]*ll;sum[rs[now]]=lazy[rs[now]]*rl; l[ls[now]]=r[ls[now]]=mx[ls[now]]=(lazy[now]^1)*ll; l[rs[now]]=r[rs[now]]=mx[rs[now]]=(lazy[now]^1)*rl; lazy[now]=-1; } void pushup(int now,int left,int right) { sum[now]=sum[ls[now]]+sum[rs[now]]; int mid=(left+right)>>1,ll=mid-left+1,rl=right-mid; if (mx[ls[now]]==ll) l[now]=ll+l[rs[now]];else l[now]=l[ls[now]]; if (mx[rs[now]]==rl) r[now]=rl+r[ls[now]];else r[now]=r[rs[now]]; mx[now]=max(r[ls[now]]+l[rs[now]],max(mx[ls[now]],mx[rs[now]])); } void modify1(int now,int left,int right,int lq,int rq,int val) { pushdown(now,left,right); if (left==lq && right==rq) { lazy[now]=val;sum[now]=lazy[now]*(right-left+1); l[now]=r[now]=mx[now]=(right-left+1)*(val^1); return; } int mid=(left+right)>>1; if (rq<=mid) modify1(ls[now],left,mid,lq,rq,val); else if (lq>=mid+1) modify1(rs[now],mid+1,right,lq,rq,val); else modify1(ls[now],left,mid,lq,mid,val),modify1(rs[now],mid+1,right,mid+1,rq,val); pushup(now,left,right); } int warn=0; int modify3(int now,int left,int right,int k) { warn++; pushdown(now,left,right); int kk=right-left+1-sum[now]; if (k>=kk) { sum[now]=right-left+1;lazy[now]=1; mx[now]=l[now]=r[now]=0; return kk; } if (left==right) { sum[now]=1;mx[now]=l[now]=r[now]=0; return 1; } int mid=(left+right)>>1,rr=mid-left+1-sum[ls[now]],ret=0; if (k<=rr) ret=modify3(ls[now],left,mid,k); else { sum[ls[now]]=mid-left+1;lazy[ls[now]]=1; mx[ls[now]]=l[ls[now]]=r[ls[now]]=0; ret=rr+modify3(rs[now],mid+1,right,k-rr); } pushup(now,left,right);return ret; } int modify2(int now,int left,int right,int l,int r,int k) { warn++; pushdown(now,left,right); if ((left==l) && (right==r)) return modify3(now,left,right,k); int mid=(left+right)>>1,ret=0; if (r<=mid) { if (mid-left+1-sum[ls[now]]>0) ret=modify2(ls[now],left,mid,l,r,k); } else if (l>=mid+1) { if (right-mid-sum[rs[now]]>0) ret=modify2(rs[now],mid+1,right,l,r,k); } else { if (mid-left+1-sum[ls[now]]) ret=modify2(ls[now],left,mid,l,mid,k); if ((k>ret) && (right-mid-sum[rs[now]])) ret+=modify2(rs[now],mid+1,right,mid+1,r,k-ret); } pushup(now,left,right);return ret; } status merge(status x,status y) { status ret=status(0,0,0,0); if (x.mx==x.len) ret.l=x.len+y.l;else ret.l=x.l; if (y.mx==y.len) ret.r=y.len+x.r;else ret.r=y.r; ret.mx=max(x.r+y.l,max(x.mx,y.mx)); ret.len=x.len+y.len; return ret; } int ask1(int now,int left,int right,int l,int r) { pushdown(now,left,right); if (left==l && right==r) return sum[now]; int mid=(left+right)>>1; if (r<=mid) return ask1(ls[now],left,mid,l,r); else if (l>=mid+1) return ask1(rs[now],mid+1,right,l,r); else return ask1(ls[now],left,mid,l,mid)+ask1(rs[now],mid+1,right,mid+1,r); } status ask2(int now,int left,int right,int lq,int rq) { pushdown(now,left,right); if ((left==lq) && (right==rq)) return status(mx[now],l[now],r[now],right-left+1); int mid=(left+right)>>1; if (rq<=mid) return ask2(ls[now],left,mid,lq,rq); else if (lq>=mid+1) return ask2(rs[now],mid+1,right,lq,rq); else return merge(ask2(ls[now],left,mid,lq,mid),ask2(rs[now],mid+1,right,mid+1,rq)); } int main() { scanf("%d%d",&n,&m); build(root,1,n); for (int i=1;i<=m;i++) { scanf("%d%d%d",&type,&l1,&r1); if (!type) modify1(root,1,n,l1,r1,0); else if (type==1) { warn=0; scanf("%d%d",&l2,&r2); int ret=ask1(root,1,n,l1,r1); modify1(root,1,n,l1,r1,0); if (ret) {int kr=modify2(root,1,n,l2,r2,ret);kr++;} } else printf("%d\n",ask2(root,1,n,l1,r1).mx); } return 0; }
以上是关于BZOJ 4592 脑洞治疗仪的主要内容,如果未能解决你的问题,请参考以下文章