1. 程式人生 > >【ZJOI2007】捉迷藏 小小的總結

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