BZOJ4592 [Shoi2015]脑洞治疗仪

来源:互联网 发布:泰国4g网络制式 频段 编辑:程序博客网 时间:2024/05/01 21:14

进行治疗实际上相当于用1覆盖一段区间,这段区间内原有的1的个数加上挖出来的1的个数等于这段区间的长度,并且这段区间的长度最长为治疗的区间长度

记录一下还剩多少挖出来的1,然后在线段树上爬出这个区间就可以了,因为是线段树上,所以找到一个区间是log的

知道了一段区间的长度,区间里有多少1,还剩多少脑组织,就能知道这段区间是否被完全覆盖

需要判断是否还剩脑组织,如果没了就返回,要不然复杂度不对

复杂度 O(m log n)

#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<algorithm>#include<iomanip>#include<vector>#include<stack>#include<queue>#include<map>#include<set>#include<bitset>using namespace std;#define MAXN 200010#define MAXM 1010#define ll long long#define INF 1000000000#define MOD 1000000007#define eps 1e-8int n,m;int s[MAXN<<2],mx[MAXN<<2],mxl[MAXN<<2],mxr[MAXN<<2],ch[MAXN<<2],s0[MAXN<<2];int MX,MXR;int V;inline void ud(int x,int y,int z){int mid=y+z>>1;s[x]=s[x<<1]+s[x<<1|1];s0[x]=s0[x<<1]+s0[x<<1|1];mx[x]=max(mxr[x<<1]+mxl[x<<1|1],max(mx[x<<1],mx[x<<1|1]));mxl[x]=mxl[x<<1];mxr[x]=mxr[x<<1|1];if(s0[x<<1]==mid-y+1){mxl[x]=s0[x<<1]+mxl[x<<1|1];}if(s0[x<<1|1]==z-mid){mxr[x]=s0[x<<1|1]+mxr[x<<1];}}inline void toch(int x,int y,int z,int cv){s0[x]=mx[x]=mxl[x]=mxr[x]=(z-y+1)*(cv^1);s[x]=(z-y+1)*cv;ch[x]=cv;}inline void pd(int x,int y,int z){if(~ch[x]){int mid=y+z>>1;toch(x<<1,y,mid,ch[x]);toch(x<<1|1,mid+1,z,ch[x]);ch[x]=-1;}}void build(int x,int y,int z){ch[x]=-1;if(y==z){s0[x]=mx[x]=mxl[x]=mxr[x]=0;s[x]=1;return ;}int mid=y+z>>1;build(x<<1,y,mid);build(x<<1|1,mid+1,z);ud(x,y,z);}void change(int x,int y,int z,int l,int r,int cv){if(y==l&&z==r){toch(x,y,z,cv);return ;}pd(x,y,z);int mid=y+z>>1;if(r<=mid){change(x<<1,y,mid,l,r,cv);}else if(l>mid){change(x<<1|1,mid+1,z,l,r,cv);}else{change(x<<1,y,mid,l,mid,cv);change(x<<1|1,mid+1,z,mid+1,r,cv);}ud(x,y,z);}int ask(int x,int y,int z,int l,int r){if(y==l&&z==r){return s[x];}pd(x,y,z);int mid=y+z>>1;if(r<=mid){return ask(x<<1,y,mid,l,r);}else if(l>mid){return ask(x<<1|1,mid+1,z,l,r);}else{return ask(x<<1,y,mid,l,mid)+ask(x<<1|1,mid+1,z,mid+1,r);}ud(x,y,z);}void toask(int x,int y,int z,int l,int r){if(y==l&&z==r){MX=max(MX,max(MXR+mxl[x],mx[x]));if(s0[x]==z-y+1){MXR+=z-y+1;}else{MXR=mxr[x];}return ;}pd(x,y,z);int mid=y+z>>1;if(r<=mid){toask(x<<1,y,mid,l,r);}else if(l>mid){toask(x<<1|1,mid+1,z,l,r);}else{toask(x<<1,y,mid,l,mid);toask(x<<1|1,mid+1,z,mid+1,r);}ud(x,y,z);}void dang(int x,int y,int z){if(y==z){if(V+s[x]>=z-y+1){V-=z-y+1-s[x];toch(x,y,z,1);}return ;}pd(x,y,z);int mid=y+z>>1;if(V+s[x]>=z-y+1){V-=z-y+1-s[x];toch(x,y,z,1);return ;}else{dang(x<<1,y,mid);if(V){dang(x<<1|1,mid+1,z);}}ud(x,y,z);}void guang(int x,int y,int z,int l,int r){if(!V){return ;}if(y==l&&z==r){if(V){dang(x,y,z);}return ;}pd(x,y,z);int mid=y+z>>1;if(r<=mid){guang(x<<1,y,mid,l,r);}else if(l>mid){guang(x<<1|1,mid+1,z,l,r);}else{guang(x<<1,y,mid,l,mid);if(V){guang(x<<1|1,mid+1,z,mid+1,r);}}ud(x,y,z);}int main(){int i,o,x,y,xx,yy;scanf("%d%d",&n,&m);build(1,1,n);for(i=1;i<=m;i++){scanf("%d",&o);if(o==0){scanf("%d%d",&x,&y);change(1,1,n,x,y,0);}if(o==1){scanf("%d%d%d%d",&x,&y,&xx,&yy);V=ask(1,1,n,x,y);change(1,1,n,x,y,0);guang(1,1,n,xx,yy);}if(o==2){scanf("%d%d",&x,&y);MX=MXR=0;toask(1,1,n,x,y);printf("%d\n",MX);}}return 0;}/*10 100 2 20 4 60 10 102 1 101 8 10 1 42 1 101 1 4 8 102 1 101 7 10 1 62 1 10*/


0 0
原创粉丝点击