[BZOJ 1095] [ZJOI 2007]Hide 捉迷藏
在BZ上连续MLE n次后,终于A了.
自己YY的动态点分写法,思路还是很清楚的,但是比较卡内存.
用到了MAP导致复杂度比其他的代码多了一个log,看来需要去借鉴一下别人怎么写的.
updata in 2017-05-25:
发现了一些没必要储存的东西.
1. 存储当前重心某子树堆的位置的MAP可以利用在重心树上的儿子记录此信息.
2.求树上距离可以用RMQ,没必要直接拿MAP记下来.
改完这两个令我颇不舒服的地方,复杂度就正常多了.
1 /*
2 动态树分治
3 BZOJ1095
4 全局路径查询
5 单点修改,全局查询
6 */
7 #include<cstdio>
8 #include<iostream>
9 #include<cstdlib>
10 #include<cstring>
11 #include<ctime>
12 #include<cmath>
13 #include<vector>
14 #include<map>
15 #include<set>
16 #include<bitset>
17 #include<algorithm>
18 #include<iomanip>
19 #include<queue>
20 #include<stack>
21 using namespace std;
22 #define ll long long
23 #define up(i,j,n) for(int i=j;i<=n;++i)
24 #define db double
25 #define piii pair< pair<int,int>,int>
26 #define pb push_back
27 #define FILE "dealing"
28 #define eps 1e-8
29 template<class T> inline bool cmin(T&a,T b){return a>b?a=b,true:false;}
30 template<class T> inline bool cmax(T&a,T b){return a<b?a=b,true:false;}
31 template<class T> inline T squ(T a){return a*a;}
32 const int maxn=100000+10,base=23,limit=3e8,inf=2000000;
33 int read(){
34 int x=0,f=1,ch=getchar();
35 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
36 while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
37 return x*f;
38 }
39 int n,Q;
40 vector<int>E[maxn];
41 struct dui{
42 priority_queue<int> q,q2;
43 void pop(){
44 while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
45 if(!q.empty())q.pop();
46 }
47 int top(){
48 while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
49 if(!q.empty())return q.top();
50 else return -1;
51 }
52 void erase(int x){
53 q2.push(x);
54 while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
55 }
56 void push(int x){
57 q.push(x);
58 while(!q.empty()&&!q2.empty()&&q.top()==q2.top())q.pop(),q2.pop();
59 }
60 int getans(){
61 int s1=top();pop();
62 int s2=top();push(s1);
63 if(s1==-1)return -1;
64 if(s2==-1)return -2;
65 return s1+s2;
66 }
67 }All,DA[maxn],MA[maxn<<1];int cnt=0;
68 int siz[maxn],vis[maxn],Mx[maxn],dep[maxn];
69 int getsize(int x,int fa){
70 siz[x]=1;
71 for(int i=0;i<E[x].size();i++)if(E[x][i]!=fa&&!vis[E[x][i]]){
72 getsize(E[x][i],x);
73 siz[x]+=siz[E[x][i]];
74 }
75 }
76 void getroot(int x,int fa,int& rt,int S){
77 Mx[x]=0;
78 for(int i=0;i<E[x].size();i++)if(E[x][i]!=fa&&!vis[E[x][i]]){
79 getroot(E[x][i],x,rt,S);
80 cmax(Mx[x],siz[E[x][i]]);
81 }
82 cmax(Mx[x],S-siz[x]);
83 if(Mx[x]<Mx[rt])rt=x;
84 }
85 int fa[maxn];
86 vector<int> F[maxn];
87 map<int,int>A[maxn],B[maxn];
88 void DFS(int x,int fa,int Cnt,int FA){
89 A[FA][x]=Cnt;
90 B[FA][x]=dep[x];
91 MA[Cnt].push(dep[x]);
92 for(int i=0;i<E[x].size();i++)if(E[x][i]!=fa&&!vis[E[x][i]]){
93 dep[E[x][i]]=dep[x]+1;
94 DFS(E[x][i],x,Cnt,FA);
95 }
96 }
97 int work(int x,int S){
98 int rt=0;
99 getroot(x,0,rt,siz[x]);
100 vis[rt]=1;
101 getsize(rt,0);x=rt;
102 cnt++;F[x].push_back(cnt);MA[cnt].push(0);
103 A[x][x]=cnt;B[x][x]=0;
104 for(int i=0;i<E[x].size();i++)if(!vis[E[x][i]]){
105 cnt++;
106 F[x].push_back(cnt);
107 dep[E[x][i]]=1;
108 DFS(E[x][i],0,cnt,x);
109 }
110 for(int i=0;i<F[x].size();i++)
111 DA[x].push(MA[F[x][i]].top());
112 int val=DA[x].getans();
113 if(val!=-1&&val!=-2)All.push(val);
114 for(int i=0;i<E[x].size();i++)if(!vis[E[x][i]]){
115 int y=work(E[x][i],siz[E[x][i]]);
116 fa[y]=x;
117 }
118 return x;
119 }
120 char s[10];
121 int f[maxn],sum;
122 void motify(int x,int FA){
123 while(x){
124 int val=DA[x].getans();
125 if(val!=-1&&val!=-2)All.erase(val);
126
127 int id=A[x][FA];
128 val=MA[id].top();if(val!=-1)DA[x].erase(val);
129 if(!f[FA])MA[id].push(B[x][FA]);
130 else MA[id].erase(B[x][FA]);
131 val=MA[id].top();if(val!=-1)DA[x].push(val);
132
133 val=DA[x].getans();
134 if(val!=-1&&val!=-2)All.push(val);
135 x=fa[x];
136 }
137 }
138 int main(){
139 freopen(FILE".in","r",stdin);
140 freopen(FILE".out","w",stdout);
141 n=read();Mx[0]=inf;sum=n;
142 up(i,2,n){
143 int x=read(),y=read();
144 E[x].push_back(y);
145 E[y].push_back(x);
146 }
147 getsize(1,0);
148 work(1,siz[1]);
149 Q=read();
150 while(Q--){
151 scanf("%s",s+1);
152 if(s[1]=='G'){
153 if(sum==0)printf("-1\n");
154 else if(sum==1)printf("0\n");
155 else printf("%d\n",All.top());
156 }
157 if(s[1]=='C'){
158 int x=read();
159 f[x]^=1;
160 if(!f[x])sum++;
161 else sum--;
162 motify(x,x);
163 }
164 }
165 return 0;
166 }