zoukankan      html  css  js  c++  java
  • 树链剖分题目


    LCA模板

    int n, m;
    int fa[MXN], sz[MXN], dep[MXN], son[MXN], top[MXN];
    std::vector<int> mp[MXN];
    void dfs1(int u,int ba,int d) {
        dep[u] = d; fa[u] = ba; sz[u] = 1; son[u] = 0;
        for(auto v: mp[u]) {
            if(v == ba) continue;
            dfs1(v, u, d + 1);
            sz[u] += sz[v];
            if(sz[v] > sz[son[u]]) son[u] = v;
        }
    }
    void rdfs(int u,int ba) {
        if(son[u]) {
            top[son[u]] = top[u];
            rdfs(son[u], u);
        }
        for(auto v: mp[u]) {
            if(v == ba || v == son[u]) continue;
            top[v] = v;
            rdfs(v, u);
        }
    }
    int LCA(int x,int y) {
        while(top[x] != top[y]) {
            if(dep[top[x]] < dep[top[y]]) swap(x, y);
            x = fa[top[x]];
        }
        return dep[x] < dep[y]? x: y;
    }
    void solve() {
        dfs1(1, 1, 1);
        top[1] = 1;
        rdfs(1, 1);
    }
    function<void(LL,LL)> dfs = [&](LL u, LL p) {
      seg[u].first = ++step;
      for(LL i = 0; i < G[u].size(); i++) {
        LL &v = G[u][i];
        if(v == p) continue;
        dfs(v, u);
      }
      seg[u].second = step;
    };
    
    

    P3384[模板]树链剖分

    链接

    #include<bits/stdc++.h> 
    #define lowbit(x) (x&(-(x)))
    #define lson rt<<1
    #define rson rt<<1|1
    #define mme(a,b) memset((a),(b),sizeof((a)))  
    #define fuck(x) cout<<"* "<<x<<"
    "
    #define iis std::ios::sync_with_stdio(false)
    #define fi first
    #define se second
    using namespace std;
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    const int MOD = 998244353;
    const int N = 1e5 + 7;
    const int MX = 2e5 + 7;
    int n, m, q, mod, root;
    struct Tree{
      int l,r,d,Sum,lazy;
    }sgt[N<<2];
    int ar[N];
    struct lp{
      int v,nex;
    }cw[MX];
    int head[MX],tot;
    int inde;
    int sz[MX],top[MX],son[MX],dep[MX],faz[MX];
    int tid[MX],rnk[MX],rtid[MX];//id->dfsid//dfsid->id//lastid
    void init(){
      tot=-1;inde=0;
      mme(head,-1);mme(son,-1);
      mme(sz,0);mme(dep,0);mme(faz,0);mme(top,0);
      mme(tid,0);mme(rtid,0);mme(rnk,0);
    }
    void push_up(int rt){
      sgt[rt].Sum=(sgt[lson].Sum+sgt[rson].Sum)%mod;
    }
    void push_down(int rt){
      if(sgt[rt].lazy){
        int c = sgt[rt].lazy;
        sgt[lson].lazy=(sgt[lson].lazy+sgt[rt].lazy)%mod;
        sgt[rson].lazy=(sgt[rson].lazy+sgt[rt].lazy)%mod;
        sgt[lson].Sum=(sgt[lson].Sum+sgt[lson].d*c%mod)%mod;
        sgt[rson].Sum=(sgt[rson].Sum+sgt[rson].d*c%mod)%mod;
        sgt[rt].lazy=0;
      }
    }
    void build(int l,int r,int rt){
      sgt[rt].l=l;sgt[rt].r=r;
      sgt[rt].d=r-l+1;
      sgt[rt].lazy=0;
      if(l==r){
        sgt[rt].Sum=ar[rnk[l]];
        return;
      }
      int mid=(l+r)>>1;
      build(l,mid,lson);build(mid+1,r,rson);
      push_up(rt);
    }
    void update(int L,int R,int c,int rt){
      int l = sgt[rt].l,r=sgt[rt].r,mid=(l+r)>>1;
      if(sgt[rt].l>R||sgt[rt].r<L)return;
      if(L<=l&&r<=R){
        sgt[rt].lazy=(c+sgt[rt].lazy)%mod;
        sgt[rt].Sum=(sgt[rt].Sum+sgt[rt].d*c%mod)%mod;
        return;
      }
      if(sgt[rt].l==sgt[rt].r)return;
      push_down(rt);
      if(L<=mid)update(L,R,c,lson);
      if(R>mid)update(L,R,c,rson);
      push_up(rt);
    }
    int query(int L,int R,int rt){
      int l = sgt[rt].l,r=sgt[rt].r,mid=(l+r)>>1;
      if(L<=l&&r<=R){
        return sgt[rt].Sum;
      }
      if(sgt[rt].l>R||sgt[rt].r<L)return 0;
      if(sgt[rt].l==sgt[rt].r)return 0;
      push_down(rt);
      int _sum = 0;
      if(L<=mid)_sum = query(L,R,lson)%mod;
      if(R>mid)_sum=(_sum+query(L,R,rson))%mod;
      return _sum;
    }
    void dfs1(int u,int fat,int depth){
      dep[u] = depth;faz[u] = fat;sz[u] = 1;
      son[u] = 0;
      for(int i=head[u];~i;i=cw[i].nex){
        int v = cw[i].v;
        if(v==fat)continue;
        dfs1(v,u,depth+1);
        sz[u] += sz[v];
        if(sz[v]>sz[son[u]]){
          son[u] = v;
        }
      }
    }
    void dfs2(int u,int t){
      tid[u] = ++inde;
      rnk[inde]=u;
      if(son[u]){
        top[son[u]] = top[u];
        dfs2(son[u],u);
      }
      for(int i=head[u];~i;i=cw[i].nex){
        int v = cw[i].v;
        if(v!=son[u]&&v!=faz[u]){
            top[v]=v;
          dfs2(v,u);
        }
      }
      rtid[u]=inde;
    }
    int path_query(int x,int y){
      int ans=0;
      int fx=top[x],fy=top[y];
      while(fx!=fy){
        if(dep[fx]>=dep[fy]){
          ans=(ans+query(tid[fx],tid[x],1))%mod;
          x=faz[fx];
        }else {
          ans=(ans+query(tid[fy],tid[y],1))%mod;
          y=faz[fy];
        }
        fx=top[x],fy=top[y];
      }
      if(tid[x]<tid[y]){
        ans=(ans+query(tid[x],tid[y],1))%mod;
      }else {
        ans=(ans+query(tid[y],tid[x],1))%mod;
      }
      return ans;
    }
    void path_update(int x,int y,int c){
      int fx=top[x],fy=top[y];
      while(fx!=fy){
        if(dep[fx]>dep[fy]){
          update(tid[fx],tid[x],c,1);
          x=faz[fx];
        }else {
          update(tid[fy],tid[y],c,1);
          y=faz[fy];
        }
        fx=top[x],fy=top[y];
      }
      if(tid[x]<tid[y]){
        update(tid[x],tid[y],c,1);
      }else {
        update(tid[y],tid[x],c,1);
      }
    }
    void add_edge(int u,int v){
      cw[++tot].v=v;cw[tot].nex=head[u];
      head[u]=tot;
      cw[++tot].v=u;cw[tot].nex=head[v];
      head[v]=tot;
    }
    void pre_build(){
      dfs1(root,root,1);
      top[root]=root;
      dfs2(root,root);
      build(1,n,1);
    }
    int main(){
      while(~scanf("%d%d%d%d",&n,&q,&root,&mod)){
        init();
        for(int i=1;i<=n;++i){
          scanf("%d",&ar[i]);
          ar[i]%=mod;
        }
        for(int i=1,u,v;i<n;++i){
          scanf("%d%d",&u,&v);
          add_edge(u,v);
        }
        pre_build();
        while(q--){
          int op;scanf("%d",&op);
          int u,v,w;
          if(op==1){
            scanf("%d%d%d",&u,&v,&w);
            w%=mod;
            path_update(u,v,w);
          }else if(op==2){
            scanf("%d%d",&u,&v);
            printf("%d
    ", path_query(u,v));
          }else if(op==3){
            scanf("%d%d",&u,&w);
            w%=mod;
            update(tid[u],rtid[u],w,1);
          }else if(op==4){
            scanf("%d",&u);
            printf("%d
    ", query(tid[u],rtid[u],1));
          }
        }
      }
      return 0;
    }
    

    牛客国庆集训派对Day6-I-清明梦超能力者黄YY

    链接

    #include<bits/stdc++.h>
    #define lson rt<<1
    #define rson rt<<1|1
    #define fi first
    #define se second
    #define mme(a,b) memset((a),(b),sizeof((a))) 
    #define iis std::ios::sync_with_stdio(false)
    #define Mod(a, b) a<b?a:a%b+b
    using namespace std;
    typedef long long LL;
    const int MXN = 2e5 + 7;
    const int mod = 1000000007;
    const int INF = 0x3f3f3f3f;
    int n, m, k;
    struct one{
        int u, v, c;
    }opt[MXN];
    std::vector<int> mp[MXN];
    int fa[MXN], dep[MXN], son[MXN], top[MXN], tid[MXN], rtid[MXN], siz[MXN];
    int inde;
    int rnk[MXN];
    int sum[MXN<<2], flag[MXN<<2];
    int ans[MXN], res[MXN<<2];
    void build(int l,int r,int rt) {
        sum[rt] = 0; flag[rt] = 0;
        if(l == r) return;
        int mid = (l + r) >> 1;
        build(l,mid,lson), build(mid+1,r,rson);
    }
    void push_up(int rt) {
        if(sum[lson] < k && sum[rson] < k) {
            sum[rt] = max(sum[lson], sum[rson]);
        }
    }
    void push_down(int rt) {
        flag[lson] += flag[rt];
        flag[rson] += flag[rt];
        sum[lson] += flag[rt];
        sum[rson] += flag[rt];
        flag[rt] = 0;
    }
    void fuck(int c,int l,int r,int rt) {
        if(sum[rt] != k) return;
        if(l == r) {
            ans[rnk[l]] = c;
            sum[rt] = -INF;
            return;
        }
        push_down(rt);
        int mid = (l + r) >> 1;
        fuck(c, l, mid, lson);
        fuck(c, mid + 1, r, rson);
        push_up(rt);
    }
    void updata(int L,int R,int c,int l,int r,int rt) {
        if(L <= l && r <= R) {
            ++ flag[rt];
            ++ sum[rt];
            fuck(c, l, r, rt);
            return;
        }
        push_down(rt);
        int mid = (l + r) >> 1;
        if(L > mid) updata(L,R,c,mid+1,r,rson);
        else if(R <= mid) updata(L,R,c,l,mid,lson);
        else {
            updata(L,mid,c,l,mid,lson);
            updata(mid+1,R,c,mid+1,r,rson);
        }
        push_up(rt);
    }
    void dfs_1(int u,int ba,int D) {
        fa[u] = ba; dep[u] = D; son[u] = 0; siz[u] = 1;
        for(auto v: mp[u]) {
            if(v == ba) continue;
            dfs_1(v, u, D+1);
            siz[u] += siz[v];
            if(siz[v] > siz[son[u]]) son[u] = v;
        }
    }
    void dfs_2(int u,int ba) {
        tid[u] = ++inde;
        rnk[inde] = u;
        if(son[u]) {
            top[son[u]] = top[u];
            dfs_2(son[u], u);
        }
        for(auto v: mp[u]) {
            if(v == ba || v == son[u]) continue;
            top[v] = v;
            dfs_2(v, u);
        }
        rtid[u] = inde;
    }
    void updata_path(int x,int y,int c) {
        int fx = top[x], fy = top[y];
        while(fx != fy) {
            if(dep[fx] <= dep[fy]) swap(fx,fy),swap(x,y);
            updata(tid[fx], tid[x], c, 1, n, 1);
            x = fa[fx];
            fx = top[x], fy = top[y];
        }
        if(tid[x] >= tid[y]) swap(x, y);
        updata(tid[x], tid[y], c, 1, n, 1);
    }
    int main() {
        scanf("%d%d%d", &n, &m, &k);
        for(int i = 1, a, b; i < n; ++i) {
            scanf("%d%d", &a, &b);
            mp[a].push_back(b);
            mp[b].push_back(a);
        }
        for(int i = 0, u, v, c; i < m; ++i) {
            scanf("%d%d%d", &opt[i].u, &opt[i].v, &opt[i].c);
        }
        dfs_1(1, 1, 1);
        top[1] = 1;
        dfs_2(1, 1);
        build(1, n, 1);
        for(int i = m-1; i >= 0; --i) {
            updata_path(opt[i].u,opt[i].v,opt[i].c);
        }
        for(int i = 1; i < n; ++i) {
            printf("%d ", ans[i]);
        }
        printf("%d
    ", ans[n]);
        return 0;
    }
    
    
  • 相关阅读:
    ZOJ 2587 Unique Attack (最小割唯一性)
    POJ 2987 Firing (最大权闭合图)
    POJ 2987 Firing (最大权闭合图)
    POJ 3469 Dual Core CPU (最小割建模)
    POJ 3469 Dual Core CPU (最小割建模)
    UVA 11426 GCD-Extreme(II) ★ (欧拉函数)
    UVA 11426 GCD-Extreme(II) ★ (欧拉函数)
    HDU 4612 Warm up (边双连通分量+DP最长链)
    HDU 4612 Warm up (边双连通分量+DP最长链)
    hdu5531 Rebuild
  • 原文地址:https://www.cnblogs.com/Cwolf9/p/10032049.html
Copyright © 2011-2022 走看看