[bzoj1095][ZJOI2007]Hide 捉迷藏(动态点分治)

来源:互联网 发布:手机淘宝脸部拍摄认证 编辑:程序博客网 时间:2024/06/05 20:31

传送门
话说我明明是抄的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 longusing 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;}