zoukankan      html  css  js  c++  java
  • bzoj1095: [ZJOI2007]Hide 捉迷藏

    神TM动态点分治。。

    然而st表又双叒叕TM挂了 sbyzh

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    
    int n;
    struct node
    {
        int x,y,next;
    }a[210000];int len,last[110000];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    
    int z,ys[110000],dep[110000];
    int f[30][210000];
    void dfs(int x,int fr) 
    {
        f[0][++z]=dep[x];ys[x]=z;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr)
            {
                dep[y]=dep[x]+1;
                dfs(y,x);
                f[0][++z]=dep[x];
            }
        }
    }
    
    int Bin[30],Log[210000];
    void get_st()
    {
        Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2;
        Log[1]=0;for(int i=2;i<=z ;i++)Log[i]=Log[i/2]+1;
        
        for(int j=1;Bin[j]<=z;j++)
            for(int i=1;i+Bin[j]-1<=z;i++)
                f[j][i]=min(f[j-1][i],f[j-1][i+Bin[j-1]]);
    }
    int RMQ(int x,int y)
    {
        x=ys[x],y=ys[y];
        if(x>y)swap(x,y);
        int k=Log[y-x+1];
        return min(f[k][x],f[k][y-Bin[k]+1]);
    }
    
    //-----------get_st---------------------用于求LCA的dep 
    
    int rt,sum;bool v[110000];
    int tot[110000],g[110000];
    void getrt(int x,int fr)
    {
        tot[x]=1,g[x]=0;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr&&v[y]==false)
            {
                getrt(y,x);
                tot[x]+=tot[y];
                g[x]=max(g[x],tot[y]);
            }
        }
        if(fr!=0)g[x]=max(g[x],sum-tot[x]);
        if(g[x]<g[rt]||rt==0)rt=x;
    }
    int fa[110000];
    void divi(int x)
    {
        v[x]=true;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(v[y]==false)
            {
                sum=tot[y],rt=0;
                getrt(y,x),fa[rt]=x;
                divi(rt);
            }
        }
    }
    
    //------------composition-----------------
    
    struct heap //为了支持删除,开两个堆 
    {
        priority_queue<int> ha,hb;
        
        void ins(int x){ha.push(x);}
        void del(int x){hb.push(x);}
        int size(){return ha.size()-hb.size();}
        
        int top()
        {
            while(hb.size()>0&&ha.top()==hb.top()) ha.pop(), hb.pop();
            if(ha.size()==0)return 0;
            return ha.top();
        }
        void pop()
        {
            while(hb.size()>0&&ha.top()==hb.top()) ha.pop(), hb.pop();
            ha.pop();
        }
        int stop()
        {
            int x=top();
            if(size()<=1)return 0;
            pop();
            
            int y=top();
            ins(x);
            return y;
        }
    }A,B[110000],C[110000];
    
    //~~~init~~~
    
    int getdis(int x,int y){return dep[x]+dep[y]-2*RMQ(x,y);}
    void turn_off(int f,int x)
    {
        if(f==x)
        {
            B[f].ins(0);
            if(B[f].size()==2)
                A.ins(B[f].top());
        }
        int ff=fa[f];if(ff==0)return ;
        
        int dis=getdis(ff,x),mmax=C[f].top();
        C[f].ins(dis);//upd C 
        if(dis>mmax)
        {
            int d1=B[ff].top()+B[ff].stop(),s1=B[ff].size();
            if(mmax!=0)B[ff].del(mmax);
            B[ff].ins(dis);//upd B
    
            int d2=B[ff].top()+B[ff].stop(),s2=B[ff].size();
            if(d1<d2)//upd A
            {
                if(s1>=2)A.del(d1);
                if(s2>=2)A.ins(d2);
            }
        }
        turn_off(ff,x);
    }
    void turn_on(int f,int x)
    {
        if(f==x)
        {
            if(B[f].size()==2)
                A.del(B[f].top());
            B[x].del(0);
        }
        int ff=fa[f];if(ff==0)return ;
        
        int dis=getdis(ff,x),mmax=C[f].top();
        C[f].del(dis);//upd C
        if(dis==mmax)
        {
            int d1=B[ff].top()+B[ff].stop(),s1=B[ff].size();
            B[ff].del(dis);
            if(C[f].top()!=0)B[ff].ins(C[f].top());//upd B
    
            int d2=B[ff].top()+B[ff].stop(),s2=B[ff].size();//upd C
            if(d1>d2)
            {
                if(s1>=2)A.del(d1);
                if(s2>=2)A.ins(d2);
            }
        }
        turn_on(ff,x);
    }
    
    //-----------let make it---------------------
    
    int cc;bool col[110000]; 
    char ss[10];
    int main()
    {
        freopen("hide.in","r",stdin);
        freopen("hide.out","w",stdout);
        
        int x,y;
        scanf("%d",&n);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            ins(x,y);ins(y,x);
        }
        
        dep[1]=0;dfs(1,0);
        get_st();
        
        sum=n,rt=0;
        getrt(1,0),fa[rt]=0;
        divi(rt);
        
        cc=0;
        for(int i=1;i<=n;i++)
            cc++, col[i]=false, turn_off(i,i);    
        int m;
        scanf("%d",&m);
        while(m--)
        {
            scanf("%s",ss+1);
            if(ss[1]=='G')
            {
                     if(cc==0)printf("-1
    ");
                else if(cc==1)printf("0
    ");
                else printf("%d
    ",A.top());
            }
            else
            {
                scanf("%d",&x);
                if(col[x]==false)
                    cc--, col[x]=true, turn_on(x,x);
                else
                    cc++, col[x]=false, turn_off(x,x);
            }
        }
        return 0;
    }
  • 相关阅读:
    Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境搭建教程
    将Windows Server 2016 打造成工作站(20161030更新)
    阿里云服务器Svn-Server无法连接
    安卓 webview背景色的设置
    安卓handler、thread实现异步任务
    多幅图像下载的时间效率问题
    gridview里item是textView、Button单击事件相应,以及按下效果的取去除
    android dialog圆角显示及解决出现的黑色棱角.(友情提示)
    Android自定义对话框(Dialog)位置,大小
    安卓selector
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8857981.html
Copyright © 2011-2022 走看看