zoukankan      html  css  js  c++  java
  • zjoi 2007 捉迷藏 动态点分治+可删堆

    https://www.luogu.org/problem/P2056

    题解:来自https://blog.csdn.net/ccsu_cat/article/details/101036382

     这代码是真的长,一码就是150行+

    特殊之处在于这个题需要维护一个可删堆

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mp make_pair
    #define pii pair<ll,ll>
    using namespace std;//head
    const int maxn=4e5+10,maxm=2e6+10;
    const ll INF=0x3f3f3f3f,mod=1e9+7;
    int casn,n,m,k;
    namespace graph{
      vector<int>g[maxn];
      bool vis[maxn];
      int all,sz[maxn],root,maxt,father[maxn];
      int _deep[maxn],_dfn[maxn],_cnt;
      int son[maxn];
      int _lca[maxn][int(log(maxn)/log(2))+1];
      int logn[maxn];
      void add(int a,int b){
        g[a].emplace_back(b);g[b].emplace_back(a);
      }
      int dfs_root(int now,int fa){
        int cnt=1;
        son[now]=0;
        for(auto to:g[now])if(to!=fa&&!vis[to]){
          int ch=dfs_root(to,now);
          son[now]=max(son[now],ch);
          cnt+=ch;
        }
        son[now]=max(son[now],all-cnt);
        if(son[now]<son[root]) root=now;
        return sz[now]=cnt;
      }
      void dfs_lca(int now,int fa){
        _dfn[now]=++_cnt;
        _lca[_cnt][0]=_deep[now]=_deep[fa]+1;
        for(auto to:g[now]) {
          if(to==fa) continue;
          dfs_lca(to,now);
          _lca[++_cnt][0]=_deep[now];
        }
      }
      class node{public:
        priority_queue<int> x,y;
        inline void push(int a){x.push(a);}
        inline void remove(int a){y.push(a);}
        inline int top(){
          while(y.size()&&x.top()==y.top())
          x.pop(),y.pop();return x.top();
        }
        inline int size(){return x.size()-y.size();}
        inline void pop(){
          while(y.size()&&x.top()==y.top())
          x.pop(),y.pop();
          x.pop();
        }
        inline int sectop(){int a=top();pop();int b=top();push(a);return b;}
      }ans0,b[maxn],c[maxn];
      void cal_st(){
        logn[0]=-1;
        rep(i,1,2e5+10) logn[i]=logn[i>>1]+1;
        rep(j,1,logn[_cnt])rep(i,1,_cnt-(1<<j)+1)
          _lca[i][j]=min(_lca[i][j-1],_lca[i+(1<<(j-1))][j-1]);
      }
      int _dis(int a,int b){
        a=_dfn[a],b=_dfn[b];
        if(a>b) swap(a,b);
        int len=logn[b-a+1];
        return min(_lca[a][len],_lca[b-(1<<len)+1][len]);
      }
      int dis(int a,int b){
        int res=_deep[a]+_deep[b]-2*_dis(a,b);
        return res;
      }
      void dfs_cal(int now,int fa){
        c[root].push(dis(now,father[root]));
        for(auto to:g[now]){
          if(to==fa||vis[to]) continue;
          dfs_cal(to,now);
        }
      }
      void pusha(int now){
        if(b[now].size()>=2) 
          ans0.push(b[now].top()+b[now].sectop());
      }
      void dela(int now){
        if(b[now].size()>=2) 
          ans0.remove(b[now].top()+b[now].sectop());
      }
      void dfs_dv(int now,int fa){
        father[now]=fa;vis[now]=1;
        b[now].push(0);
        dfs_cal(now,0);
        for(auto to:g[now]){
          if(vis[to]) continue;
          all=sz[to],root=0;
          dfs_root(to,0);
          int tmp=root;
          dfs_dv(root,now);
          b[now].push(c[tmp].top());
        }
        pusha(now);
      }
      void on(int pos){
        dela(pos);
        b[pos].remove(0);
        pusha(pos);
        for(int now=pos;father[now];now=father[now]){
          dela(father[now]);
          b[father[now]].remove(c[now].top());
          c[now].remove(dis(pos,father[now]));
          if(c[now].size()) b[father[now]].push(c[now].top());
          pusha(father[now]);
        }
      }
      void off(int pos){
        dela(pos);
        b[pos].push(0);
        pusha(pos);
        for(int now=pos;father[now];now=father[now]){
          dela(father[now]);
          if(c[now].size()) b[father[now]].remove(c[now].top());
          c[now].push(dis(pos,father[now]));
          b[father[now]].push(c[now].top());
          pusha(father[now]);
        }
      }
      void init(int n){
        _cnt=0;
        dfs_lca(1,0);
        cal_st();
        son[0]=n;
        all=n;root=0;
        dfs_root(1,0);
        dfs_dv(root,0);
      }
    }
    using namespace graph;
    bool sw[maxn];
    int main() {IO;
      int a,b;
      rep(i,1,maxn-5) logn[i]=logn[i>>1]+1;
      cin>>n;
      rep(i,2,n){
        cin>>a>>b;
        add(a,b);
      }
      init(n);
      int cnt=n;
      cin>>m;
      while(m--){
        string s;cin>>s;
        if(s[0]=='G'){
          if(cnt<=1) cout<<cnt-1<<endl;
          else cout<<ans0.top()<<endl;
        }else {
          int pos;cin>>pos;
          if(!sw[pos]) on(pos),--cnt;
          else off(pos),++cnt;
          sw[pos]^=1;
        }
      }
    }
    
  • 相关阅读:
    简明Python3教程 12.问题解决
    简明Python3教程 11.数据结构
    【SPOJ 694】Distinct Substrings
    【codeforces Manthan, Codefest 17 C】Helga Hufflepuff's Cup
    【CF Manthan, Codefest 17 B】Marvolo Gaunt's Ring
    【CF Manthan, Codefest 17 A】Tom Riddle's Diary
    【SPOJ 220】 PHRASES
    【POJ 3261】Milk Patterns
    【POJ 3294】Life Forms
    【POJ 1226】Substrings
  • 原文地址:https://www.cnblogs.com/nervendnig/p/11630122.html
Copyright © 2011-2022 走看看