【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 }

你可能感兴趣的:(in)