传送门
话说我明明是抄的po姐的代码,为什么我的23s,po姐的14s???
看来我代码已经很接近颜值了。。
其实这题就是维护好多个堆,每个点两个,再来一个全局堆就好了。
具体还是看po姐的blog吧:
http://blog.csdn.net/popoqqq/article/details/44461423
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
inline int read(){
int x=0;char ch=' ';int f=1;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int N=1e5+5;
struct Priority_Queue{
priority_queue<int> heap,del;
void push(int x){
heap.push(x);
}
void erase(int x){
del.push(x);
}
void pop(){
while(del.size()&&heap.top()==del.top())
heap.pop(),del.pop();
heap.pop();
}
int top(){
while( del.size() && heap.top()==del.top() )
heap.pop(),del.pop();
return heap.top();
}
int second_top(){
int temp=top();pop();
int re=top();push(temp);
return re;
}
int size(){
return heap.size()-del.size();
}
}h1[N],h2[N],all;
struct edge{
int to,next;
}e[N<<1];
int n,q,nowsize,tot;
int can[N],size[N];
int head[N];
inline void addedge(int x,int y){
e[++tot].to=y;e[tot].next=head[x];head[x]=tot;
}
inline void Insert(Priority_Queue &s){
if(s.size()>=2){
all.push(s.top()+s.second_top());
}
}
inline void Erase(Priority_Queue &s){
if(s.size()>=2){
all.erase(s.top()+s.second_top());
}
}
int dep[N],f[N];
int father[N],vis[N];
int st[17][N];
inline void dfs(int x,int fa){
dep[x]=dep[fa]+1;
size[x]=1;
st[0][x]=fa;
for(int k=1;k<=16&&(1<<k)<=dep[x];k++){
st[k][x]=st[k-1][st[k-1][x]];
}
for(int i=head[x];i;i=e[i].next){
int u=e[i].to;
if(u==fa)continue;
dfs(u,x);
size[x]+=size[u];
}
}
inline int getlca(int x,int y){
if(x==y)return x;
if(dep[x]>dep[y])swap(x,y);
for(int k=16;k>=0;k--){
if(dep[st[k][y]]>=dep[x]){
y=st[k][y];
}
}
if(x==y)return x;
for(int k=16;k>=0;k--){
if(st[k][x]!=st[k][y]){
x=st[k][x];
y=st[k][y];
}
}
return st[0][x];
}
inline int getsize(int x,int fa){
int res=1;
for(int i=head[x];i;i=e[i].next){
int u=e[i].to;
if(u==fa||vis[u])continue;
res+=getsize(u,x);
}
return res;
}
inline void getroot(int x,int fa,int &root){
size[x]=1;f[x]=0;
for(int i=head[x];i;i=e[i].next){
int u=e[i].to;
if(u==fa)continue;
if(vis[u])continue;
getroot(u,x,root);
size[x]+=size[u];
f[x]=max(f[x],size[u]);
}
f[x]=max(f[x],nowsize-size[x]);
if(f[x]<f[root])root=x;
}
inline void getdis(int x,int fa,int root,int dis,Priority_Queue &s){
s.push(dis+1);
for(int i=head[x];i;i=e[i].next){
int u=e[i].to;
if(u==fa)continue;
if(vis[u])continue;
getdis(u,x,root,dis+1,s);
}
}
inline int build(int x){
int root=0;f[0]=0x3f3f3f3f;
nowsize=getsize(x,0);
getroot(x,0,root);
h2[root].push(0);
vis[root]=1;
for(int i=head[root];i;i=e[i].next){
int u=e[i].to;
if(vis[u])continue;
Priority_Queue s;
getdis(u,root,root,0,s);
int tmp=build(u);
father[tmp]=root;h1[tmp]=s;
h2[root].push(h1[tmp].top());
}
Insert(h2[root]);
return root;
}
inline int disxy(int x,int y){
int lca=getlca(x,y);
return dep[x]+dep[y]-dep[lca]*2;
}
inline void turn_on(int x){
Erase(h2[x]);
h2[x].push(0);
Insert(h2[x]);
for(int i=x;father[i];i=father[i]){
Erase(h2[father[i]]);
if(h1[i].size()){
h2[father[i]].erase(h1[i].top());
}
h1[i].push(disxy(father[i],x));
if(h1[i].size()){
h2[father[i]].push(h1[i].top());
}
Insert(h2[father[i]]);
}
}
inline void turn_off(int x){
Erase(h2[x]);
h2[x].erase(0);
Insert(h2[x]);
for(int i=x;father[i];i=father[i]){
Erase(h2[father[i]]);
if(h1[i].size()){
h2[father[i]].erase(h1[i].top());
}
h1[i].erase(disxy(father[i],x));
if(h1[i].size()){
h2[father[i]].push(h1[i].top());
}
Insert(h2[father[i]]);
}
}
int main(){
n=read();
for(int i=1;i<n;i++){
int x=read(),y=read();
addedge(x,y);addedge(y,x);
}
dfs(1,0);
build(1);
q=read();
for(int i=1;i<=n;i++){
can[i]=0;
}
int now=0;
while(q--){
char ch[3];
scanf("%s",ch);
if(ch[0]=='G'){
if(now==n)printf("-1");
else printf("%d\n",all.top());
}
else{
int x=read();
if(can[x]){
now--;
can[x]=0;
turn_on(x);
}
else{
now++;
can[x]=1;
turn_off(x);
}
}
}
return 0;
}