这题真的是纠结了好久,去年暑假做了好久没能搞出来,昨天再回过头来做,发现有些思路了。

贡献了n次wa之后终于改对了。

 int l1,r1;//标记左右两端分别是什么颜色
 int ll,rr;//记录左右两端的长度是多少
 int Blen,Wlen;//记录该区间中连续黑,连续白石头的最长长度是多少
 int cp;//标记该区间是否被整个turn

需要记录下来这些变量,最重要的是cp,它记录的是该区间是否被整个转变颜色。

View Code
  1 # include<stdio.h>
  2 # include<string.h>
  3 # include<stdlib.h>
  4 # define N 100005
  5 struct node{
  6     int l,r;
  7     int l1,r1;//标记左右两端分别是什么颜色
  8     int ll,rr;//记录左右两端的长度是多少
  9     int Blen,Wlen;//记录该区间中连续黑,连续白石头的最长长度是多少
 10     int cp;//标记该区间是否被整个turn
 11 
 12 }tree[4*N];
 13 int a[N];
 14 int Max(int c,int b)
 15 {
 16     return c>b?c:b;
 17 }
 18 int Min(int c,int b)
 19 {
 20     return c<b?c:b;
 21 }
 22 void change(int t)
 23 {
 24     int temp;
 25     tree[t].l1=(tree[t].l1+1)%2;
 26     tree[t].r1=(tree[t].r1+1)%2;
 27     tree[t].cp=(tree[t].cp+1)%2;
 28     temp=tree[t].Blen;
 29     tree[t].Blen=tree[t].Wlen;
 30     tree[t].Wlen=temp;
 31 }
 32 void update_t(int t)
 33 {
 34     tree[t].l1=tree[2*t].l1;
 35     tree[t].r1=tree[2*t+1].r1;
 36     
 37     tree[t].ll=tree[2*t].ll;
 38     tree[t].rr=tree[2*t+1].rr;
 39     
 40     tree[t].Blen=Max(tree[2*t].Blen,tree[2*t+1].Blen);
 41     tree[t].Wlen=Max(tree[2*t].Wlen,tree[2*t+1].Wlen);
 42     
 43     if(tree[2*t].r1==tree[2*t+1].l1)
 44     {
 45         if(tree[2*t].r1==1) //如果为黑
 46         {
 47             tree[t].Blen=Max(tree[t].Blen,tree[2*t].rr+tree[2*t+1].ll);
 48         }
 49         else
 50         {
 51             tree[t].Wlen=Max(tree[t].Wlen,tree[2*t].rr+tree[2*t+1].ll);
 52         }
 53         
 54         if(tree[2*t].ll==tree[2*t].r-tree[2*t].l+1) tree[t].ll+=tree[2*t+1].ll;
 55         
 56         if(tree[2*t+1].ll==tree[2*t+1].r-tree[2*t+1].l+1) tree[t].rr+=tree[2*t].rr;
 57     }
 58 }
 59 void bulid(int l,int r,int t)
 60 {
 61     int mid;
 62     tree[t].l=l;
 63     tree[t].r=r;
 64     tree[t].cp=0;
 65     if(l==r) 
 66     {
 67         tree[t].ll=tree[t].rr=1;
 68         if(a[l]==0)
 69         {
 70             tree[t].l1=0;
 71             tree[t].r1=0;    
 72             tree[t].Blen=0;
 73             tree[t].Wlen=1;
 74         }
 75         else
 76         {
 77             tree[t].l1=1;
 78             tree[t].r1=1;
 79             tree[t].Blen=1;
 80             tree[t].Wlen=0;
 81         }
 82         return;
 83     }
 84     mid=(l+r)/2;
 85     bulid(l,mid,2*t);
 86     bulid(mid+1,r,2*t+1);
 87     update_t(t);
 88 }
 89 void update(int l,int r,int t)
 90 {
 91     int temp;
 92     if(tree[t].l==l && tree[t].r==r)
 93     {
 94         change(t);
 95         return;
 96     }
 97     if(tree[t].cp==1)
 98     {
 99         tree[t].cp=0;
100         change(2*t);
101         change(2*t+1);
102     }
103     if(r<=tree[2*t].r)
104     {
105         update(l,r,2*t);
106     }
107     else if(l>=tree[2*t+1].l)
108     {
109         update(l,r,2*t+1);
110     }
111     else
112     {
113         update(l,tree[2*t].r,2*t);
114         update(tree[2*t+1].l,r,2*t+1);
115     }
116     update_t(t);
117 }
118 int query(int l,int r,int t)
119 {
120     int temp,ans1,ans2,t1;
121     if(tree[t].l==l && tree[t].r==r) return tree[t].Blen;
122     if(tree[t].cp)
123     {
124         tree[t].cp=0;
125         change(2*t);
126         change(2*t+1);
127     }
128     if(r<=tree[2*t].r) return query(l,r,2*t);
129     else if(l>=tree[2*t+1].l) return query(l,r,2*t+1);
130     else
131     {
132         ans1=query(l,tree[2*t].r,2*t);
133         ans2=query(tree[2*t+1].l,r,2*t+1);
134         t1=Max(ans1,ans2);
135         if(tree[2*t].r1==tree[2*t+1].l1)
136         {
137             if(tree[2*t].r1==1)
138             {
139                 ans1=Min(tree[2*t].r-l+1,tree[2*t].rr);
140                 ans2=Min(r-tree[2*t+1].l+1,tree[2*t+1].ll);
141                 t1=Max(t1,ans1+ans2);
142             }
143         }
144         return t1;
145     }
146 }
147 int main()
148 {
149     int i,n,m,from,to,flag;
150 
151     while(scanf("%d",&n)!=EOF)
152     {
153         for(i=1;i<=n;i++)
154             scanf("%d",&a[i]);
155         bulid(1,n,1);
156         scanf("%d",&m);
157         while(m--)
158         {
159             scanf("%d%d%d",&flag,&from,&to);
160             if(flag==1) update(from,to,1);
161             else
162             {
163                 printf("%d\n",query(from,to,1));
164             }
165         }
166     }
167     return 0;
168 }

 

 

 

 

posted on 2012-04-11 19:19  奋斗青春  阅读(315)  评论(0编辑  收藏  举报