【FOJ】1968 Twinkling lights III

  1 #include<cstdio>
  2 #define MAXN 500010
  3 struct node
  4 {
  5     int sum;
  6     int v1,v0;
  7     int left0,left1;
  8     int right0,right1;
  9 };
 10 node tree[MAXN<<2];
 11 int cover[MAXN<<2],lazy[MAXN<<2];
 12 inline int MAX(int x,int y)
 13 {
 14     return x>y?x:y;
 15 }
 16 inline int MIN(int x,int y)
 17 {
 18     return x>y?y:x;
 19 }
 20 inline void swap(int &x,int &y)
 21 {
 22     int temp=x;
 23     x=y;
 24     y=temp;
 25 }
 26 inline void PushUp(int mid,int L,int R,int rt)
 27 {
 28     tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
 29     tree[rt].left0=tree[rt<<1].left0;
 30     tree[rt].left1=tree[rt<<1].left1;
 31     tree[rt].right0=tree[rt<<1|1].right0;
 32     tree[rt].right1=tree[rt<<1|1].right1;
 33     if(tree[rt].left0==mid-L+1)
 34         tree[rt].left0+=tree[rt<<1|1].left0;
 35     if(tree[rt].left1==mid-L+1)
 36         tree[rt].left1+=tree[rt<<1|1].left1;
 37     if(tree[rt].right0==R-mid)
 38         tree[rt].right0+=tree[rt<<1].right0;
 39     if(tree[rt].right1==R-mid)
 40         tree[rt].right1+=tree[rt<<1].right1;
 41     tree[rt].v0=MAX(tree[rt<<1].v0,tree[rt<<1|1].v0);
 42     tree[rt].v0=MAX(tree[rt].v0,tree[rt<<1].right0+tree[rt<<1|1].left0);
 43     tree[rt].v1=MAX(tree[rt<<1].v1,tree[rt<<1|1].v1);
 44     tree[rt].v1=MAX(tree[rt].v1,tree[rt<<1].right1+tree[rt<<1|1].left1);
 45 }
 46 void Build(int L,int R,int rt)
 47 {
 48     cover[rt]=-1;
 49     lazy[rt]=0;
 50     if(L==R)
 51     {
 52         tree[rt].left1=tree[rt].right1=tree[rt].v1=tree[rt].sum=1;
 53         tree[rt].left0=tree[rt].right0=tree[rt].v0=0;
 54     }
 55     else
 56     {
 57         int mid=(L+R)>>1;
 58         Build(L,mid,rt<<1);
 59         Build(mid+1,R,rt<<1|1);
 60         PushUp(mid,L,R,rt);
 61     }
 62 }
 63 inline void FXOR(int L,int R,int rt)
 64 {
 65     if(cover[rt]!=-1)
 66     {
 67         cover[rt]^=1;
 68         tree[rt].left1=tree[rt].right1=tree[rt].v1=tree[rt].sum=(R-L+1)*cover[rt];
 69         tree[rt].left0=tree[rt].right0=tree[rt].v0=(R-L+1)*(cover[rt]^1);
 70     }
 71     else
 72     {
 73         lazy[rt]^=1;
 74         tree[rt].sum=R-L+1-tree[rt].sum;
 75         swap(tree[rt].left0,tree[rt].left1);
 76         swap(tree[rt].right0,tree[rt].right1);
 77         swap(tree[rt].v0,tree[rt].v1);
 78     }
 79 }
 80 inline void PushDown(int mid,int L,int R,int rt)
 81 {
 82     if(cover[rt]!=-1)
 83     {
 84         cover[rt<<1]=cover[rt<<1|1]=cover[rt];
 85         lazy[rt<<1]=lazy[rt<<1|1]=0;
 86         tree[rt<<1].left1=tree[rt<<1].right1=tree[rt<<1].v1=tree[rt<<1].sum=(mid-L+1)*cover[rt];
 87         tree[rt<<1|1].left1=tree[rt<<1|1].right1=tree[rt<<1|1].v1=tree[rt<<1|1].sum=(R-mid)*cover[rt];
 88         tree[rt<<1].left0=tree[rt<<1].right0=tree[rt<<1].v0=(mid-L+1)*(cover[rt]^1);
 89         tree[rt<<1|1].left0=tree[rt<<1|1].right0=tree[rt<<1|1].v0=(R-mid)*(cover[rt]^1);
 90         cover[rt]=-1;
 91     }
 92     else if(lazy[rt])
 93     {
 94         FXOR(L,mid,rt<<1);
 95         FXOR(mid+1,R,rt<<1|1);
 96         lazy[rt]=0;
 97     }
 98 }
 99 void Update(int x,int y,int val,int L,int R,int rt)
100 {
101     if(x<=L&&R<=y)
102     {
103         cover[rt]=val;
104         lazy[rt]=0;
105         tree[rt].left1=tree[rt].right1=tree[rt].v1=tree[rt].sum=(R-L+1)*val;
106         tree[rt].left0=tree[rt].right0=tree[rt].v0=(R-L+1)*(val^1);
107     }
108     else
109     {
110         int mid=(L+R)>>1;
111         PushDown(mid,L,R,rt);
112         if(mid>=x)
113             Update(x,y,val,L,mid,rt<<1);
114         if(y>mid)
115             Update(x,y,val,mid+1,R,rt<<1|1);
116         PushUp(mid,L,R,rt);
117     }
118 }
119 void Change(int x,int y,int L,int R,int rt)
120 {
121     if(x<=L&&R<=y)
122         FXOR(L,R,rt);
123     else
124     {
125         int mid=(L+R)>>1;
126         PushDown(mid,L,R,rt);
127         if(mid>=x)
128             Change(x,y,L,mid,rt<<1);
129         if(y>mid)
130             Change(x,y,mid+1,R,rt<<1|1);
131         PushUp(mid,L,R,rt);
132     }
133 }
134 int Sum(int x,int y,int L,int R,int rt)
135 {
136     if(x<=L&&R<=y)
137         return tree[rt].sum;
138     int mid=(L+R)>>1,ans=0;
139     PushDown(mid,L,R,rt);
140     if(mid>=x)
141         ans+=Sum(x,y,L,mid,rt<<1);
142     if(y>mid)
143         ans+=Sum(x,y,mid+1,R,rt<<1|1);
144     return ans;
145 }
146 int Query(int x,int y,int L,int R,int rt)
147 {
148     if(x<=L&&R<=y)
149         return tree[rt].v1;
150     int mid=(L+R)>>1,ans=0;
151     PushDown(mid,L,R,rt);
152     if(mid>=x)
153         ans=MAX(ans,Query(x,y,L,mid,rt<<1));
154     if(y>mid)
155         ans=MAX(ans,Query(x,y,mid+1,R,rt<<1|1));
156     ans=MAX(ans,MIN(mid-x+1,tree[rt<<1].right1)+MIN(y-mid,tree[rt<<1|1].left1));
157     return ans;
158 }
159 int main()
160 {
161     char ch;
162     int n,m,x,y;
163     while(~scanf("%d%d",&n,&m))
164     {
165         Build(1,n,1);
166         while(m--)
167         {
168             scanf(" %c%d%d",&ch,&x,&y);
169             if(ch=='C')
170                 Update(x,y,0,1,n,1);
171             else if(ch=='S')
172                 Update(x,y,1,1,n,1);
173             else if(ch=='A')
174                 Change(x,y,1,n,1);
175             else if(ch=='Q')
176                 printf("%d\n",Sum(x,y,1,n,1));
177             else
178                 printf("%d\n",Query(x,y,1,n,1));
179         }
180     }
181     return 0;
182 }

转载于:https://www.cnblogs.com/DrunBee/archive/2012/05/24/2516191.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值