• 【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 }
    新博客:www.zhixiangli.com
  • 相关阅读:
    使用高精度计算斐波那契数列 c++
    纪中9日T4 2298. 异或
    洛谷 P1416 攻击火星
    线段树小结
    纪中5日T3 1566. 幸运锁(lucky.pas/c/cpp)
    Title
    Title
    Title
    Title
    Title
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2516191.html
Copyright © 2020-2023  润新知