zoukankan      html  css  js  c++  java
  • 【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
    ",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
    ",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
    ");
                    else if(num_black==1) printf("0
    ");
                    else printf("%d
    ",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);
                }
            }
        }
    
  • 相关阅读:
    【C++】几个简单课本例题
    【汇编】AX内容依次倒排序
    【汇编】课本第三章例题
    【汇编】补码的理解+标志寄存器的相关探索
    【记录】台式机的组装
    【记录】.bin文件 到 .vdi文件的转换教程
    【汇编】1.汇编环境的搭建:DOSBox的安装
    docker的常用命令,以及postgressql的启动
    Docker中容器的备份、恢复和迁移
    C# 常见面试问题汇总
  • 原文地址:https://www.cnblogs.com/ofsxb/p/5149357.html
Copyright © 2011-2022 走看看