zoukankan      html  css  js  c++  java
  • gym 102059A 树链剖分后odt维护区间

    题意

    一棵树

    多次修改,每次修改一个点到根的所有边的颜色,并询问现在有哪些颜色染了恰好$m$条边

    题解:

    稍加思考可以知道,从某个点到根节点的颜色数,均摊复杂度很低,因此,可以考虑珂朵莉树维护重链剖分

    这里也记录一下珂朵莉树的代码

    代码:

    #include<bits/stdc++.h>
    #define endl '
    '
    #define ll long long
    #define ull unsigned long long
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define all(x) x.begin(),x.end()
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
    #define per(ii,a,b) for(int ii=b;ii>=a;--ii)
    #define forn(ii,x) for(int ii=head[x];ii;ii=edge[ii].next)
    using namespace std;
    const int maxn=2e5+20,maxm=2e6+10;
    const int INF=0x3f3f3f3f;
    const ll mod=1e9+7;
    int casn,n,m,k,col[maxn],ans[maxn];
    class odtree{public:
      struct segnode{int l,r,c;bool operator <(const segnode &a)const{return r<a.r;}};
      set<segnode> nodes;
      void split(int pos){auto it=nodes.lower_bound({pos,pos});
        if(it==nodes.end()||(it->l)>pos||(it->r)==pos) return ;
        int l=it->l,r=it->r,c=it->c;
        nodes.erase(it);nodes.insert({l,pos,c});nodes.insert({pos+1,r,c});
      }
      void update(int l,int r,int c){
        split(l-1);split(r);
        while(1){auto it=nodes.lower_bound({l,l});
          if(it==nodes.end()||(it->l)>r)  break;
          if(it->c){--ans[col[it->c]];col[it->c]-=(it->r)-(it->l)+1;++ans[col[it->c]];}
          nodes.erase(it);
        }
        --ans[col[c]];col[c]+=r-l+1;++ans[col[c]];
        nodes.insert({l,r,c});
      }
    }tree;
    namespace chain{
      struct data_e{int to,next;}edge[maxn<<1];
      int head[maxn],nume,mp[maxn];
      int ltop[maxn],fa[maxn],deep[maxn];
      int sz[maxn],remp[maxn],son[maxn],cnt;
      inline void addedge(int a,int b){edge[++nume]={b,head[a]};head[a]=nume;}
      void init(){rep(i,1,n) head[i]=0;cnt=nume=0;}
      void dfs1(int now,int pre,int d){
        deep[now]=d,fa[now]=pre,sz[now]=1,son[now]=0;
        forn(i,now){int to=edge[i].to;
          if(to!=pre) {
            dfs1(to,now,d+1);sz[now]+=sz[to];
            if(sz[to]>sz[son[now]]) son[now]=to;
          }
        }
      }
      void dfs2(int now,int pre,int sp){
        ltop[now]=sp;mp[now]=++cnt;remp[cnt]=now;
        if(son[now])  dfs2(son[now],now,sp);
        forn(i,now){int to=edge[i].to;
          if(to!=son[now]&&to!=pre) dfs2(to,now,to);
        }
      }
      void gao(int st=1){dfs1(st,0,0);dfs2(st,0,st);}
      void update(int now,int c){
        while(now>1){
          int l=max(mp[ltop[now]],2),r=mp[now];
          if(l<=r) tree.update(l,r,c);
          now=fa[ltop[now]];
        }
      }
    };
    int main() {IO;
      cin>>n>>m>>k;
      rep(i,1,n-1){int a,b;
        cin>>a>>b;
        chain::addedge(a,b);chain::addedge(b,a);
      }
      ans[0]=m;
      chain::gao();
      tree.nodes.insert({2,n,0});
      while(k--){int a,b,c;
        cin>>a>>b>>c;
        chain::update(a,b);
        cout<<ans[c]<<endl;
      }
      return 0;
    }
    
  • 相关阅读:
    Understanding about Baire Category Theorem
    Isometric embedding of metric space
    Convergence theorems for measurable functions
    Mindmap for "Principles of boundary element methods"
    Various formulations of Maxwell equations
    Existence and uniqueness theorems for variational problems
    Kernels and image sets for an operator and its dual
    [loj6498]农民
    [luogu3781]切树游戏
    [atAGC051B]Three Coins
  • 原文地址:https://www.cnblogs.com/nervendnig/p/10642087.html
Copyright © 2011-2022 走看看