【BZOJ1095】【ZJOI2007】捉迷藏 [动态点分治]

题解:

好像还是比较简单的

对每个重心向下一层重心连边

树高是log的

我们对每一层维护两个信息

1.所有节点到上一层重心的距离

2.所有儿子的1堆的堆顶

另外开个总的堆 维护每一层最长+次长

修改是nlog^2的

洛谷上的时限真紧啊。。

卡时卡不过

 代码:

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+100;
const int INF=1e9;
#define IL inline
#define rint register int
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (ritn i=t;i>=h;i--)
char ss[1<<24],*A=ss,*B=ss;
IL char gc()
{
  return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; 
}
template<class T>IL void read(T &x)
{
  rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
  while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; 
}
IL void read2(char &x)
{
  rint c; while (c=gc(),c!='G'&&c!='C'); x=c; 
}
char sr[1<<24],z[20]; int C=-1,Z;
template <class T> void wer(T x)
{
  if (x<0) sr[++C]='-',x=-x;
  while (z[++Z]=x%10+48,x/=10);
  while (sr[++C]=z[Z],--Z); sr[++C]='\n';
}
struct PQ{
  struct cmp{
    IL bool operator() (int x,int y)
    {
      return(x<y);
    }
  };
  priority_queue<int>Q1,Q2;
  IL void push(int x) {Q1.push(x);}
  IL void erase(int x) {Q2.push(x);} 
  IL int top()
  {
    while (Q2.size()&&Q2.top()==Q1.top()) Q1.pop(),Q2.pop();
    if (Q1.size()) return(Q1.top()); else return(-INF);
  }
  IL void pop()
  {
    while (Q2.size()&&Q2.top()==Q1.top()) Q1.pop(),Q2.pop();
    Q1.pop();
  }
  IL int sec_top()
  {
    int tmp=top();
    if (tmp>0) pop();
    int x=top(); 
    if (tmp>0) push(tmp);
    return x;
  }
}Q1[N],Q2[N],QQ;
int n,l,head[N],dep[N],bz[20][N],f[N],son[N],fa[N],rt,ans1[N],ans2[N];
int sum;
bool vis[N];
struct re{
  int a,b;
}a[N*2];
void arr(int x,int y)
{
  a[++l].a=head[x];
  a[l].b=y;
  head[x]=l;
}
IL int lca(int x,int y)
{
  if (dep[x]<dep[y]) swap(x,y);
  for (int i=19;i>=0;i--)
    if (dep[bz[i][x]]>=dep[y]) x=bz[i][x];
  if (x==y) return(x);
  for (int i=19;i>=0;i--)
    if (bz[i][x]!=bz[i][y]) x=bz[i][x],y=bz[i][y];
  return(bz[0][x]);
}
IL int js(int x,int y)
{
  int kk=lca(x,y);
  return(dep[x]+dep[y]-2*dep[kk]);
}
void dfs(int x,int fa)
{
  int u=head[x]; dep[x]=dep[fa]+1; bz[0][x]=fa;
  while (u)
  {
    int v=a[u].b;
    if (v!=fa) dfs(v,x);
    u=a[u].a;
  }
}
void fr(int x,int fa)
{
  f[x]=0; son[x]=1;
  int u=head[x];
  while (u)
  {
    int v=a[u].b;
    if (v!=fa&&vis[v])
    {
      fr(v,x);
      f[x]=max(f[x],son[v]);
      son[x]+=son[v];
    }
    u=a[u].a;
  }
  f[x]=max(f[x],sum-son[x]);
  if (f[x]<f[rt]) rt=x; 
}
void fd(int x,int y,int kk,int z)
{
  int jl=js(x,kk);
  Q1[z].push(jl);
  int u=head[x];
  while (u)
  {
    int v=a[u].b;
    if (v!=y&&vis[v]) fd(v,x,kk,z);
    u=a[u].a;
  }
}
void solve(int x,int y,int z)
{
  //cout<<z<<endl; 
  int u=head[x]; fa[x]=y; vis[x]=0;
  if (x!=1)
  {
    fd(x,y,y,x),Q2[y].push(Q1[x].top()); 
    ans1[x]=Q1[x].top(); 
  }
  Q2[x].push(0);
  while (u)
  {
    int v=a[u].b;
    if (vis[v])
    {
      rt=0; sum=son[v];
      fr(v,x); 
      solve(rt,x,z+1);
    }
    u=a[u].a;
  }
}
int cnt1,cnt2;
IL int cl(int x,int y)
{
  cnt1++;
  if (y>ans1[x])
  {
    Q2[fa[x]].erase(ans1[x]);
    ans1[x]=y;
    Q2[fa[x]].push(ans1[x]);
    return(1);
  }
  return(0);
}
IL int cl3(int x,int y)
{
  if (y==ans1[x])
  {
    Q2[fa[x]].erase(ans1[x]);
    ans1[x]=Q1[x].top();
    Q2[fa[x]].push(ans1[x]);
    return(1);
  }
  return(0);
}
IL void cl2(int x)
{
  cnt2++;
  int num=Q2[x].top()+Q2[x].sec_top();
  if (num!=ans2[x])
  {
    if (ans2[x]>0) QQ.erase(ans2[x]);
    ans2[x]=num;
    if (ans2[x]>0) QQ.push(ans2[x]);
  }
}
IL void change(int x,int y)
{
  if (y==1) Q2[x].push(0); else Q2[x].erase(0);
  cl2(x);
  rint z=x;
  while (z!=1)
  {
    rint jl=js(x,fa[z]);
    if (y==1)
    {
      Q1[z].push(jl);
      if (cl(z,jl)) cl2(fa[z]);
    } else
    {
      Q1[z].erase(jl);
      if (cl3(z,jl)) cl2(fa[z]);
    }
    z=fa[z];
  }
}
bool t[N];
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
//  ios::sync_with_stdio(false);
  read(n);
  for (int i=1;i<=n-1;i++)
  {
    int x,y;
    read(x); read(y); arr(x,y); arr(y,x);
  }
  memset(vis,1,sizeof(vis));
  dfs(1,0);
  rep(i,1,19)
    rep(j,1,n)
      bz[i][j]=bz[i-1][bz[i-1][j]];
  f[0]=INF; solve(1,0,0);
  rep(i,1,n)
  {
    int num; num=ans2[i]=Q2[i].top()+Q2[i].sec_top();
    if (num>0) QQ.push(num); 
  }
  memset(t,1,sizeof(t));
  int m;
  read(m);
  char kk;
  rep(i,1,m)
  {
    int x;
    read2(kk);
    if (kk=='G')
    {
      wer(QQ.top());
    } else
    {
      read(x);
      if (t[x]==1)
      {
        t[x]=0;
        change(x,0);
      } else
      {
        t[x]=1;
        change(x,1);
      }
    }
  }
 // cout<<cnt1<<endl<<cnt2<<endl;
 fwrite(sr,1,C+1,stdout);
  return 0;
}

 

posted @ 2018-07-13 23:31  尹吴潇  阅读(143)  评论(0编辑  收藏  举报