【bzoj 1858】 [Scoi2010]序列操作 线段树

来源:互联网 发布:企业组织架构优化 编辑:程序博客网 时间:2024/05/18 04:00

第一次学习线段树的时候写的第一道题,想一想那时候天真的自己还是搞了一整天,用了将近标程2倍的代码量,记得那时候当屏幕出现ac是激动的样子,哎,人老了

#include<cstdio>#include<cstring>#include<iostream>#define maxn 100010#define lson u<<1,l,mid#define rson u<<1|1,mid+1,rusing namespace std;int n,m,k;struct node{int l,r,s,l1,r1,l0,r0,add,one,zero,vis;//one表示最多有多少个连续的1 zero表示最多有多少个连续的0 }nod[maxn*14];void swap2(int *a, int *b){    int temp;    temp = *a;    *a = *b;    *b = temp;}void pushdown(int u){int add=nod[u].add;int l=u<<1;int r=u<<1|1;if(add==1){nod[l].add=nod[r].add=1;nod[l].s=nod[r].s=0;nod[l].one=nod[l].l1=nod[l].r1=0;nod[r].one=nod[r].l1=nod[r].r1=0;nod[l].zero=nod[l].l0=nod[l].r0=nod[l].r-nod[l].l+1;nod[r].zero=nod[r].l0=nod[r].r0=nod[r].r-nod[r].l+1;}if(add==2){nod[l].add=nod[r].add=2;nod[l].s=nod[l].r-nod[l].l+1;nod[r].s=nod[r].r-nod[r].l+1;nod[l].zero=nod[l].l0=nod[l].r0=0;nod[r].zero=nod[r].l0=nod[r].r0=0;nod[l].one=nod[l].l1=nod[l].r1=nod[l].r-nod[l].l+1;nod[r].one=nod[r].l1=nod[r].r1=nod[r].r-nod[r].l+1;}if(add==3){bool ok1=1,ok2=1;if(nod[l].add==1||nod[l].add==2&&nod[l].vis!=-1){pushdown(l);}if(nod[r].add==1||nod[r].add==2&&nod[r].vis!=-1){pushdown(r);}if(nod[l].add==3){nod[l].add=0;ok1=0;}if(nod[r].add==3){nod[r].add=0;ok2=0;}if(ok1)nod[l].add=3;if(ok2)nod[r].add=3;nod[l].s=nod[l].r-nod[l].l+1-nod[l].s;nod[r].s=nod[r].r-nod[r].l+1-nod[r].s;swap2(&nod[l].l0,&nod[l].l1);swap2(&nod[l].r0,&nod[l].r1);swap2(&nod[l].one,&nod[l].zero);swap2(&nod[r].l0,&nod[r].l1);swap2(&nod[r].r0,&nod[r].r1);swap2(&nod[r].one,&nod[r].zero);}nod[u].add=0;}void pushup(int u){        if(nod[u].add)pushdown(u);nod[u].s=nod[u<<1].s+nod[u<<1|1].s;nod[u].zero=max(max(nod[u<<1].zero,nod[u<<1|1].zero),nod[u<<1].r0+nod[u<<1|1].l0);nod[u].one=max(max(nod[u<<1].one,nod[u<<1|1].one),nod[u<<1].r1+nod[u<<1|1].l1);int llen=nod[u<<1].r-nod[u<<1].l +1;int rlen=nod[u<<1|1].r-nod[u<<1|1].l +1;int l=u<<1;int r=u<<1|1;if(nod[l].l1==llen){nod[u].l1=nod[l].l1 +nod[r].l1;}    if(nod[r].r1==rlen){nod[u].r1=nod[r].r1 +nod[l].r1;}if(nod[l].l1!=llen){nod[u].l1 =nod[l].l1;}if(nod[r].r1!=rlen){nod[u].r1 =nod[r].r1;}if(nod[l].l0==llen){nod[u].l0=nod[l].l0 +nod[r].l0;}    if(nod[r].r0==rlen){nod[u].r0=nod[r].r0 +nod[l].r0;}if(nod[l].l0!=llen){nod[u].l0 =nod[l].l0;}if(nod[r].r0!=rlen){nod[u].r0 =nod[r].r0;}}void build(int u,int l,int r){nod[u].l=l,nod[u].r=r;if(l==r){int x;scanf("%d",&x);nod[u].vis=-1;nod[u<<1|1].add=-1;nod[u].s=x;if(x==1){nod[u].one=1;nod[u].zero=0;nod[u].l1=1;nod[u].r1=1;nod[u].l0=0;nod[u].r0=0;}else{nod[u].one=0;nod[u].zero=1;nod[u].l1=0;nod[u].r1=0;nod[u].l0=1;nod[u].r0=1;}return;}int mid=(l+r)>>1;build(lson);build(rson);pushup(u);}void update(int u,int l,int r ,int x,int y,int add){   if(nod[u].add)pushdown(u);if(l==x&&r==y){if(add==0){nod[u].add=1;nod[u].s=0;nod[u].one=nod[u].l1=nod[u].r1=0;nod[u].zero=nod[u].l0=nod[u].r0=nod[u].r-nod[u].l+1;}if(add==1){nod[u].add=2;nod[u].s=nod[u].r-nod[u].l+1;nod[u].one=nod[u].l1=nod[u].r1=nod[u].r-nod[u].l+1;nod[u].zero=nod[u].l0=nod[u].r0=0;}if(add==2){nod[u].add=3;nod[u].s=nod[u].r-nod[u].l+1-nod[u].s;swap2(&nod[u].l0,&nod[u].l1);swap2(&nod[u].r0,&nod[u].r1);swap2(&nod[u].one,&nod[u].zero);}return;}int mid=(l+r)>>1;if(x>mid)update(rson,x,y,add);    else if(y<=mid)update(lson,x,y,add);else{update(lson,x,mid,add);update(rson,mid+1,y,add);}pushup(u);}int query1(int u,int l,int r,int x,int y){if(x==l&&y==r){return nod[u].s;}if(nod[u].add)pushdown(u);int mid=(l+r)>>1;if(x>mid)return query1(rson,x,y);else if(y<=mid)return query1(lson,x,y);else return query1(lson,x,mid)+query1(rson,mid+1,y);}int query(int u,int a,int b,int ok){if(ok){//左 if(nod[u].r-nod[u].r1<a){return b-a+1;}else return nod[u].r1;}else{if(nod[u].l1+a>b)return b-a+1;else return nod[u].l1;}}int query2(int u,int l,int r,int x,int y){if(x==l&&r==y){return nod[u].one;}if(nod[u].add)pushdown(u);int mid=(l+r)>>1;if(x>mid)return query2(rson,x,y);else if(y<=mid)return query2(lson,x,y);else {return max(max(query2(lson,x,mid),query2(rson,mid+1,y)),query(u<<1,x,mid,1)+query(u<<1|1,mid+1,y,0));}}int main(){scanf("%d%d",&n,&m);build(1,1,n);while(m--){int x,a,b;scanf("%d%d%d",&x,&a,&b);a++;b++;if(x==0)update(1,1,n,a,b,x);if(x==1)update(1,1,n,a,b,x);if(x==2)update(1,1,n,a,b,x);if(x==3){printf("%d\n",query1(1,1,n,a,b));}if(x==4)printf("%d\n",query2(1,1,n,a,b));}return 0;}


0 0
原创粉丝点击