【ZJOI2007】捉迷藏 小小的總結
2019-01-09
22:56:33
終於終於把這道題目做掉了。。。
做了兩個晚上。。不知道為什麼自己如此之笨。。
在洛谷上斷斷續續一共交了24次,感覺自己都要被封號了。
昨天花半個晚上從零開始研究動態的 澱粉質 點分治,又研究了好久的標程,然後又動手寫了半個晚上。
好不容易過了樣例,交到洛谷上一測,滿屏的 MLE 然後把氧氣優化關掉 TLE ?!!!? (手動懵逼
開始了漫長的 找不同(對比標程) 之旅,找了很久都沒有結果,就回家了。
還嘲笑了一波 標稱那堆神祕的分層操作,不知道哪裡來的一些RMQ操作,我用倍增就可以求距離了(這是個Flag,這是第二天啪啪打臉的伏筆)
第二天
中午放學一回家就開始檢查程式,又交了好幾次,每一次都是零分,每一次都是MLE(連WA的機會都不給我嗎!!)
我真的感覺我的程式和標程除了倍增求距離的方法不同其它的幾乎都沒有差別了好嗎?!(坐等打臉)
去上學 去上學 這幾天停課複習會考科目(12號會考),春哥說:“辣麼簡單的考試你們擔心什麼啦~”
晚自習繼續來到機房修改程式。
EXM??? 我居然發現我把重心 vis掉的地方寫錯了 果然,照著標程寫會受懲罰的。。。
自信滿滿地交上去一看 只有20分!(還T了一組。。
路漫漫其修遠兮
涼 真的找不到錯啊啊啊啊啊啊啊啊! 痛苦!!!
冷靜地寫了對拍
鎮定地把中間資料輸出來調
冷漠地尋找錯誤答案與正確答案之間的蛛絲馬跡
鎮靜地把資料規模調到1e5
我終於終於發現 我的倍增寫錯了!!!!!
父親節點 f[x][0] 完全賦錯值了,直接就寫成了 f[x][0]=fa (...)
改好後信心滿滿地交上去
90分。。。有一組超時了(還開了O2優化)
冷靜下來 我思考了一下,每次都倍增的話不是會很慢嗎?!
題目的查詢有那麼多次 肯定超時啊!
難怪標程用了ST表來查公共祖先
難怪有一個神祕的RMQ 就是來求LCA的啊!!
ST表可以通過 O(nlogn) 的複雜度代價來得到 O(1) 查詢的啊。
啪啪啪 打臉
感到了自負對我深深地惡意。。
然後馬不停蹄地開始改倍增,全部換成RMQ。
折騰了十幾分鍾,再次提交。
還是90! 第四組居然 WA了!! 五雷轟頂!!
又找了好久的錯,才發現 DFS 時 由於寫太快,少了一條語句。。
然後終於AC了
完結撒花!!
一道題目寫了這麼久,真的要好好反思一下了,寫程式時一定要帶著腦子思考,不能照著標程寫啊。
“剽竊”別人的智慧結晶是不會有好下場的。。
附上寫到麻木的200行程式碼
1 #include<iostream>
2 #include<cstdio>
3 #include<cstdlib>
4 #include<cstring>
5 #include<string>
6 #include<ctime>
7 #include<cmath>
8 #include<algorithm>
9 #include<cctype>
10 #include<iomanip>
11 #include<queue>
12
13 #define For(i,a,b) for(int i=a;i<=b;++i)
14 #define Dwn(i,a,b) for(int i=a;i>=b;--i)
15 #define Pn putchar('\n')
16
17 using namespace std;
18 const int N=1e5+10;
19 struct Heap {
20 priority_queue<int> h, d;
21 void add(int x){
22 h.push(x);
23 return;
24 }
25 void del(int x){
26 d.push(x);
27 return;
28 }
29 void AorP(int x,int f){
30 if(f) add(x);
31 else del(x);
32 return;
33 }
34 void fix(){
35 while(d.size()&&h.top()==d.top())
36 h.pop(),d.pop();
37 return;
38 }
39 void pop(){
40 fix();
41 h.pop();
42 return;
43 }
44 int fst(){
45 fix();
46 return h.top();
47 }
48 int scd(){
49 int a,b;
50 a=fst();
51 pop();
52 b=fst();
53 add(a);
54 return b;
55 }
56 int size(){
57 return h.size()-d.size();
58 }
59 } s1[N], s2[N], s3;
60
61 int head[N],nxt[N*2],v[N*2],cnt=1;
62 int siz[N],f[N*2][21],dis[N],Mxs[N],Wfa[N];
63 bool vis[N*2];
64 int n,m,x,y,root,tot,Frt,Qsum=0,LD[N],Q;
65 char c[20];
66
67
68 inline void read(int &v){
69 v=0;
70 char c=getchar();
71 while(c<'0'||c>'9')c=getchar();
72 while(c>='0'&&c<='9')v=v*10+c-'0',c=getchar();
73 }
74 void write(int x){
75 if(x>9)write(x/10);
76 int xx=x%10;
77 putchar(xx+'0');
78 }
79 void add(int ux,int vx){
80 cnt++;
81 nxt[cnt]=head[ux]; head[ux]=cnt; v[cnt]=vx;
82 cnt++;
83 nxt[cnt]=head[vx]; head[vx]=cnt; v[cnt]=ux;
84 }
85
86 void dfsRT(int x,int fa){
87 siz[x]=1; Mxs[x]=0;
88 for(int i=head[x];i;i=nxt[i]){
89 int vv=v[i];
90 if(vv==fa||vis[i])continue;
91 dfsRT(vv,x);
92 siz[x]+=siz[vv];
93 Mxs[x]=max(Mxs[x],siz[vv]);
94 }
95 if(tot-siz[x]>Mxs[x])Mxs[x]=tot-siz[x];
96 if(Mxs[x]<Mxs[root])root=x;
97 }
98 int getWRT(int x,int fa,int sz){
99 root=0; tot=sz; Mxs[0]=2147483600;
100 dfsRT(x,fa);
101 return root;
102 }
103 void dfsBD(int x,int fa,int dep,Heap &s){
104 s.add(dep);
105 for(int i=head[x];i;i=nxt[i]){
106 int vv=v[i];
107 if(vis[i]||vv==fa)continue;
108 dfsBD(vv,x,dep+1,s);
109 }
110 }
111 void AddS3(Heap &s){
112 if(s.size()>=2){
113 s3.add(s.fst()+s.scd());
114 }
115 return;
116 }
117 void DelS3(Heap &s){
118 if(s.size()>=2){
119 s3.del(s.fst()+s.scd());
120 }
121 }
122 void work(int x){
123 s2[x].add(0);
124 for(int i=head[x];i;i=nxt[i]){
125 int vv=v[i];
126 if(vis[i])continue;
127 vis[i]=vis[i^1]=1;
128 Heap s;
129 dfsBD(vv,0,1,s);
130 int nxtRt=getWRT(vv,x,siz[vv]);
131 Wfa[nxtRt]=x;
132 s1[nxtRt]=s;
133 s2[x].add(s1[nxtRt].fst());
134 work(nxtRt);
135 }
136 AddS3(s2[x]);
137 return;
138 }
139
140
141 int pos[2*N][21],dfx[N*2],fr[N],dpx[N*2],dep[N],ID=0;
142 void dfsLCA(int x,int d,int fa){
143 fr[x]=++ID;
144 dpx[ID]=d; dep[x]=d;
145 for(int i=head[x];i;i=nxt[i]){
146 int vv=v[i];
147 if(vv==fa)continue;
148 dfsLCA(vv,d+1,x);
149 ID++;
150 dpx[ID]=d;
151 }
152 }
153 void inLCA(){
154 For(i,1,ID)f[i][0]=dpx[i];
155 for(int j=1;(1<<j)<=ID;++j)
156 for(int i=1;i+(1<<j)-1<=ID;++i){
157 f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
158 }
159 }
160
161 int LCA(int x,int y){
162 int l=fr[x]; int r=fr[y];
163 if(x==y)return 0;
164 if(l>r)swap(l,r);
165 int Kx=-1;
166 int dx=r-l+1;
167 while((1<<(Kx+1))<=dx)Kx++;
168 int ans;
169 ans=min(f[r-(1<<Kx)+1][Kx],f[l][Kx]);
170 return ans;
171 }
172
173
174 int Dis(int x,int y){
175 return dep[x]+dep[y]-2*LCA(x,y) ;
176 }
177
178 void upD(int x,int fg){
179 DelS3(s2[x]);
180 s2[x].AorP(0,fg);
181 AddS3(s2[x]);
182 for(int u=x;Wfa[u];u=Wfa[u]){
183 DelS3(s2[Wfa[u]]);
184 if(s1[u].size())
185 s2[Wfa[u]].del(s1[u].fst());
186 s1[u].AorP(Dis(Wfa[u],x),fg);
187 if(s1[u].size())
188 s2[Wfa[u]].add(s1[u].fst());
189 AddS3(s2[Wfa[u]]);
190 }
191 return;
192 }
193 int main(){
194 //freopen("ex.in","r",stdin);
195 //freopen("ex.out","w",stdout);
196 memset(vis,0,sizeof(vis));
197 // memset(f,-1,sizeof(f));
198 read(n);
199 For(i,1,n-1){
200 read(x); read(y); add(x,y);
201 }
202 Frt=getWRT(1,0,n);
203 dfsLCA(Frt,0,0); inLCA();
204 work(Frt);
205 read(Q);
206 Qsum=n;
207 For(i,1,Q){
208 scanf("%s",c); ;
209 if(c[0]=='C'){
210 read(x);
211 upD(x,LD[x]);
212 if(LD[x])Qsum++;
213 else Qsum--;
214 LD[x]=LD[x]^1;
215 }else{
216 if(Qsum==1)write(0),Pn;
217 if(Qsum==0)putchar('-'),putchar('1'),Pn;
218 if(Qsum>=2){
219 int fn=s3.fst();
220 write(fn);
221 Pn;
222 }
223 }
224 }
225 return 0;
226 }