• 【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]='
    ';
    }
    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;
    }
  • 相关阅读:
    9、 docker容器数据卷
    第十八章 MySQL数据库优化
    第十七章 MySQL的VIP漂移和Atlas
    第十六章 MHA高可用(续)
    第一章 shell基础
    第十五章 MHA高可用
    第十四章 MySQL的各种主从
    第十三章 MySQL的主从复制
    第十二章 MySQL的恢复与备份
    第十一章 MySQL日志详解
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9307943.html
Copyright © 2020-2023  润新知