这题真的是纠结了好久,去年暑假做了好久没能搞出来,昨天再回过头来做,发现有些思路了。
贡献了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 }