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('
')
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 }