【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏

神犇们的一眼码农题 我做了2.5天!!!!!!!!!!!!!!!!!!!!!!!!!!

不想写题解了 但网上的没有几个能看 有留言的话就在写!

不少题解用LCA求距离 然而我 TLE+MLE

于是用一种奇怪的方法 vector来记录距离
再加上奇怪的卡内存姿势终于过掉了!

/**************************************************************
    Problem: 1095
    User: sxb_201
    Language: C++
    Result: Accepted
    Time:10332 ms
    Memory:143244 kb
****************************************************************/
 
 #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #define MAXN 100010
    using namespace std;
    struct H
    {
        priority_queue<int> A,B;
         
        int size()
        {
            return A.size()-B.size();
        }
        void push(int x)
        {
            A.push(x);
        }
        void out(int x)
        {
            B.push(x);
            while(!B.empty()&&B.top()==A.top()) B.pop(),A.pop();
        }
        int top_1()
        {
            while(!B.empty()&&B.top()==A.top()) B.pop(),A.pop();
            return A.top();
        }
        int top_2()
        {
            int tmp_1,tmp_2;
            tmp_1=top_1();
            A.pop();
            tmp_2=top_1();
            A.push(tmp_1);
            return tmp_2;
        }
    }Q[MAXN],P[MAXN],ANS;int cnt=0; 
    int g[MAXN],num[MAXN*2],nnext[MAXN*2],tot;
    inline void Add(int x,int y){tot++;nnext[tot]=g[x];g[x]=tot;num[tot]=y;}
    int fa_root[MAXN],fa_tmp[MAXN],fa_son[MAXN];
    vector<int>fa_num[MAXN];
    int n,m;
    int sum,root,max_son,size[MAXN];
    bool b[MAXN],is_black[MAXN];
    int mmax[MAXN];
    inline void Get_Root(int x,int fa,int lenth,int rt,int frt)
    {   //cerr<<x<<' '<<fa<<endl;
        Q[rt].push(lenth);
        fa_num[x].push_back(lenth);
      // printf("%d\n",lenth); 
        int son=0;
        size[x]=1;
        for(int i=g[x];i;i=nnext[i])
        if(num[i]!=fa&&!b[num[i]])
        {
            Get_Root(num[i],x,lenth+1,rt,frt);
            size[x]+=size[num[i]];
            son=max(son,size[num[i]]);
        }
        son=max(son,sum-size[x]); //cout<<max_son<<' '<<size[x]<<endl;
        if(son<max_son) 
        {
            max_son=son;
            root=x;
            fa_root[root]=frt;
            fa_son[root]=rt;
        }
    }
    inline void Up(int x)
    {
        if(mmax[x]!=0) ANS.out(mmax[x]);
        if(P[x].size()<2){mmax[x]=0;return ;}
         
        mmax[x]=P[x].top_1()+P[x].top_2();
        //cout<<x<<' '<<mmax[x]<<endl;
        ANS.push(mmax[x]);
    }
    void Dfs_Size(int x,int fa)
    {
    //  cerr<<x<<endl;
        size[x]=1;
        for(int i=g[x];i;i=nnext[i])
        if(!b[num[i]]&&num[i]!=fa)
        {
            Dfs_Size(num[i],x);
            size[x]+=size[num[i]];
        }
    }
    void Do(int x)
    {
    //  cerr<<x<<endl;
        b[x]=true;
        
        for(int i=g[x];i;i=nnext[i])
        if(!b[num[i]])
        {
             
            root=num[i];
            Dfs_Size(num[i],-1);
            sum=size[num[i]];//cout<<sum<<endl;
            max_son=n+1;
            Get_Root(num[i],-1,1,++cnt,x); 
           // printf("%d %d\n",sum,max_son);
            P[x].push(Q[cnt].top_1()); //cout<<x<<' '<<num[i]<<endl;
            Do(root);
        }
        P[x].push(0);
        Up(x);
    }
    void Change(int x,int lenth,bool is_add)
    {
    //  cout<<x<<' '<<lenth<<' '<<is_add<<endl;
        int fa=fa_root[x],son=fa_son[x];// cout<<fa<<' '<<son<<' '<<Q[son].size()<<endl;
        if(is_add==true)
        {
            if(Q[son].size()==0||Q[son].top_1()<lenth)
            {
                if(Q[son].size()!=0) P[fa].out(Q[son].top_1());
                Q[son].push(lenth);
                P[fa].push(lenth);
            }
            else
                Q[son].push(lenth);
        }
        else
        {
            if(Q[son].top_1()==lenth)
            {
                P[fa].out(lenth);
                Q[son].out(lenth);
                if(Q[son].size()!=0)
                    P[fa].push(Q[son].top_1());
                 
               // cout<<fa<<' '<<lenth<<' '<<Q[son].top_1()<<endl;
            }
            else
                Q[son].out(lenth);
        }//cout<<fa<<endl;
     //   cout<<fa<<' '<<mmax[fa]<<endl;
        Up(fa);
      //    cout<<mmax[fa]<<endl;
      //    cout<<'*'<<ANS.top_1()<<endl;
    }
    int main()
    {
    //  freopen("a.in","r",stdin);
    //  freopen("a.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            Add(x,y);
            Add(y,x);
        }   // cerr<<tot;
        max_son=n+1; sum=n;
        Do(1); 
         
        int num_black=n;
        for(int i=1;i<=n;i++) is_black[i]=true;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            char c;getchar();c=getchar();
            if(c=='G')
            {
                if(num_black==0) printf("-1\n");
                else if(num_black==1) printf("0\n");
                else printf("%d\n",ANS.top_1());
            }
            else
            {
                 
                int x;scanf("%d",&x);
                if(is_black[x]==true)
                {
                    num_black--;
                    is_black[x]=false;
                    P[x].out(0);
                }
                else
                {
                    num_black++;
                    is_black[x]=true;
                    P[x].push(0);
                }
                int tmp=fa_num[x].size();
                int nn=1;
                for(int i=x;fa_root[i]!=0;i=fa_root[i],nn++) Change(i,fa_num[x][tmp-nn],is_black[x]);
                Up(x);
            }
        }
    }

你可能感兴趣的:(【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏)