bzoj1095 捉迷藏

我去,传说中的动态点分治入门题,想了我几个小时还是不知道怎么处理让不同子树对父亲节点产生贡献,我的方法无论怎么样都会被同一子树的信息影响,然后Orz了一波 PoPoQQQ,Hzwer大爷,对堆的处理很巧妙!具体的自己yy吧 (不过bzoj过了,spoj上Re了,不知道什么鬼)

/**************************************************************
    Problem: 1095
    User: Clare
    Language: C++
    Result: Accepted
    Time:7056 ms
    Memory:94404 kb
****************************************************************/
 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
 
#define N 100010
#define INF 0x3f3f3f3f
 
int n,Sum,root,ans,total;
struct Edge{
    int to,next,value;
}edge[N*2],edge1[2000000];
int head[N],head1[N],tot,tot1;
int size[N],f[N],son[N];
bool done[N],White[N];
char S[5];
struct Heap{
    priority_queue A,B;
    void Push(int k){A.push(k);}
    void Erase(int k){B.push(k);}
    void Pop()
    {
        while(B.size()&&A.top()==B.top())
            A.pop(),B.pop();
        A.pop();
    }
    int Top()
    {
        while(B.size()&&A.top()==B.top())
            A.pop(),B.pop();
        return !A.size()?0:A.top();
    }
    int size(){return (int)A.size()-(int)B.size();}
    int S_top()
    {
        if(size()<2)return 0;
        int x=Top();Pop();
        int y=Top();Push(x);
        return y;
    }
}Ans,B[N],C[N];
 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
 
void Addedge1(int u,int v,int w)
{
    tot1++;edge1[tot1].next=head1[u];edge1[tot1].to=v;edge1[tot1].value=w;head1[u]=tot1;
}
 
void Addedge(int u,int v,int w)
{
    tot++;edge[tot].next=head[u];edge[tot].to=v;edge[tot].value=w;head[u]=tot;
    tot++;edge[tot].next=head[v];edge[tot].to=u;edge[tot].value=w;head[v]=tot;
}
 
void Get_root(int k,int fa)
{
    size[k]=1;f[k]=0;
    for(int i=head[k];i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(v==fa||done[v])
            continue;
        Get_root(v,k);
        size[k]+=size[v];
        f[k]=max(f[k],size[v]);
    }
    f[k]=max(f[k],Sum-f[k]);
    if(f[k]tmp)
        {
            int Max=B[Fa_pos].Top()+B[Fa_pos].S_top(),Size=B[Fa_pos].size();
            if(tmp)
                B[Fa_pos].Erase(tmp);
            B[Fa_pos].Push(edge1[ti].value);
            int Now_max=B[Fa_pos].Top()+B[Fa_pos].S_top();
            if(Now_max>Max)
            {
                if(Size>=2)Ans.Erase(Max);
                if(B[Fa_pos].size()>=2)Ans.Push(Now_max);
            }
        }
    }
}
 
void Turn_on(int k)
{
    for(int i=head1[k];i;i=edge1[i].next)
    {
        int pos=edge1[i].to;
        if(pos==k)
        {
            if(B[pos].size()==2)Ans.Erase(B[pos].Top());
            B[pos].Erase(0);
        }
        int ti=edge1[i].next;
        if(!ti)return;
        int Fa_pos=edge1[ti].to,tmp=C[pos].Top();
        C[pos].Erase(edge1[ti].value);
        if(edge1[ti].value==tmp)
        {
            int Max=B[Fa_pos].Top()+B[Fa_pos].S_top(),Size=B[Fa_pos].size();
            B[Fa_pos].Erase(tmp);
            if(C[pos].Top())
                B[Fa_pos].Push(C[pos].Top());
            int Now_max=B[Fa_pos].Top()+B[Fa_pos].S_top();
            if(Now_max=2)Ans.Erase(Max);
                if(B[Fa_pos].size()>=2)Ans.Push(Now_max);
            }
        }
    }
}
 
int main()
{
    n=read();
    for(int i=1;i<=n-1;i++)
    {
        White[i]=true;
        int x=read(),y=read();
        Addedge(x,y,1);
    }
    White[n]=true;
    Sum=n;f[0]=INF;root=0;
    Get_root(1,root);
    Rebuild(root);
    for(int i=1;i<=n;i++)
        C[i].Push(0);
    for(int i=1;i<=n;i++)
    {
        total++;Turn_off(i);
    }
    int Q=read();
    while(Q--)
    {
        scanf("%s",S);
        if(S[0]=='G')
        {
            if(total==0)
                printf("%d\n",-1);
            else if(total==1)
                printf("%d\n",0);
            else printf("%d\n",Ans.Top());
        }
        else
        {
            int x=read();
            White[x]^=1;
            if(!White[x])Turn_on(x),total--;
            else Turn_off(x),total++;
        }
    }
    return 0;
}


你可能感兴趣的:(c++,动态点分治)