• bzoj4771 七彩树


    卧槽调了一晚上

    想法很简单

    用$set$维护不同颜色的树链的并,支持链加和单点查询

    具体我们可以差分

    于是就是单点加,子树和

    考虑深度

    我们写一个主席树,第$i$个版本只考虑前$i$层

    查询$d + dep[x]$深度的树中$x$子树和即可

    调调调

    想5min写一晚上

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
        for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 100010;
    int n,m,lastans;
    int c[maxn],id[maxn];
    int fa[maxn],dep[maxn],size[maxn],bl[maxn];
    int ref[maxn],pos[maxn],last[maxn],dfn;
    int first[maxn],targ[maxn << 1],nx[maxn << 1],cnt;
    inline void add(int u,int v){targ[++cnt] = v,nx[cnt] = first[u],first[u] = cnt;}
    inline void ins(int u,int v){add(u,v),add(v,u);}
    set<int> cs[maxn];
    set<int>::iterator it;
    inline void dfs1(int u)
    {
        size[u]=1;pos[u] = ++dfn;ref[dfn] = u;
        for(int i=first[u];i;i=nx[i])
        {
            if(targ[i]==fa[u])continue;
            dep[targ[i]]=dep[u]+1;
            fa[targ[i]]=u;
            dfs1(targ[i]);
            size[u]+=size[targ[i]];
        }
        last[u] = dfn;
    }
    inline void dfs2(int u,int idc)
    {
        int k=0;
        bl[u]=idc;
        for(int i=first[u];i;i=nx[i])
            if(dep[targ[i]]>dep[u] && size[targ[i]]>size[k])
                k=targ[i];
        if(k==0)return;
        dfs2(k,idc);
        for(int i=first[u];i;i=nx[i])
            if(dep[targ[i]]>dep[u] && k!=targ[i])
                dfs2(targ[i],targ[i]);
    }
    inline int lca(int x,int y)
    {
        while(bl[x] != bl[y])
        {
            if(dep[bl[x]] < dep[bl[y]])swap(x,y);
            x = fa[bl[x]];
        }
        return dep[x] < dep[y] ? x : y;
    }
    int root[maxn],ls[maxn << 6],rs[maxn << 6],val[maxn << 6],ToT;
    inline void Insert(int &x,int pre,int l,int r,int pos,int v)
    {
        x = ++ToT;val[x] = val[pre] + v;
        if(l == r)return;
        int mid = (l + r) >> 1;
        if(pos <= mid)rs[x] = rs[pre],Insert(ls[x],ls[pre],l,mid,pos,v);
        else ls[x] = ls[pre],Insert(rs[x],rs[pre],mid + 1,r,pos,v);
    }
    inline int query(int x,int l,int r,int L,int R)
    {
        if(L <= l && r <= R)return val[x];
        int mid = (l + r) >> 1,ans = 0;
        if(L <= mid)ans += query(ls[x],l,mid,L,R);
        if(R > mid)ans += query(rs[x],mid + 1,r,L,R);
        return ans;
    }
    bool cmp(int u,int v){return dep[u] < dep[v];}
    int main()
    {
        int T = read();
        while(T--)
        {
            cnt = 0,dfn = 0,ToT = 0,lastans = 0;
            int p = 1;
            n = read(),m = read();
            for(int i=1;i<=n;i++)c[i] = read(),cs[i].clear(),id[i] = i,first[i] = 0;
            for(int i=2;i<=n;i++){int u = read();ins(u,i);}
            dfs1(1);dfs2(1,1);sort(id + 1,id + n + 1,cmp);
            root[0] = 0;int x,y;
            for(int i=0;i<n;i++)
            {
                if(i)root[i] = root[i - 1];
                while(p <= n && dep[id[p]] <= i)
                {
                    x = 0,y = 0;int pcol = c[id[p]];
                    it = cs[pcol].lower_bound(pos[id[p]]);
                    if(it != cs[pcol].end())y = ref[*it];
                    if(it != cs[pcol].begin())x = ref[*--it];
                    Insert(root[i],root[i],1,n,pos[id[p]],1);
                    if(x)Insert(root[i],root[i],1,n,pos[lca(x,id[p])],-1);
                    if(y)Insert(root[i],root[i],1,n,pos[lca(y,id[p])],-1);
                    if(x && y)Insert(root[i],root[i],1,n,pos[lca(x,y)],1);
                    cs[pcol].insert(pos[id[p]]),++p;
                }
            }
            while(m--)
            {
                x = read(),y = read();
                x = x ^ lastans,y = min(dep[x] + (y ^ lastans),n - 1);
                printf("%d
    " ,lastans = query(root[y],1,n,pos[x],last[x]));
            }
        }
    }
    View Code

    手已经不健康了

  • 相关阅读:
    广域网(ppp协议、HDLC协议)
    0120. Triangle (M)
    0589. N-ary Tree Preorder Traversal (E)
    0377. Combination Sum IV (M)
    1074. Number of Submatrices That Sum to Target (H)
    1209. Remove All Adjacent Duplicates in String II (M)
    0509. Fibonacci Number (E)
    0086. Partition List (M)
    0667. Beautiful Arrangement II (M)
    1302. Deepest Leaves Sum (M)
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9629977.html
Copyright © 2020-2023  润新知