• 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

    手已经不健康了

  • 相关阅读:
    mysql 中文字段排序( 按拼音首字母排序) 的查询语句
    纯css3样式属性制作各种图形图标
    10个超有用的网页设计工具和资源
    手风琴导航效果实现
    css3动画导航实现
    java实现将资源文件转化成sql语句导入数据库
    select实现输入模糊匹配与选择双重功能
    js一些问题总结
    java实现excel与mysql的导入导出
    《C++程序设计》朝花夕拾
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9629977.html
Copyright © 2020-2023  润新知