• BZOJ4771 七彩树


    貌似是道经典题(?强行增加代码量就是了= =

    考虑维护树链的并,用线段树维护差分就可以了

    差分:

    关键点+1

    两个相邻:LCA-1

    再考虑深度限制,直接上个主席树就好了

    因为主席树要排序后插入 所以会对上面的差分带来后效性

    如果两边都有点的话 LCA(左,右)+1

    突然发现PKUWC的D1T2其实就是这个东西...

    考虑是树上联通块 大概就是对于边计算这个,对于点也计算一个 然后就可以FFT以后容斥...

    行吧当时的水平写出虚树+链剖我很知足了= =

    //Love and Freedom.
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<set>
    #include<cassert>
    #define ll long long
    #define inf 20021225
    #define N 100100
    #define pb push_back
    #define IT set<int>::iterator
    using namespace std;
    int read()
    {
        int s=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
        return f*s;
    }
    struct edge{int to,lt;}e[N];
    int in[N],cnt,f[N][18],dep[N],dfn[N],tms,idfn[N],sz[N];
    void add(int x,int y)
    {
        e[++cnt].to=y; e[cnt].lt=in[x]; in[x]=cnt;
    }
    void dfs(int x)
    {
        dfn[x]=++tms; idfn[tms]=x; sz[x]=1;
        for(int i=1;i<18;i++)    f[x][i]=f[f[x][i-1]][i-1];
        for(int i=in[x];i;i=e[i].lt)
        {
            int y=e[i].to; dep[y]=dep[x]+1;
            f[y][0]=x; dfs(y); sz[x]+=sz[y];
        }
    }
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y])    swap(x,y);
        int len=dep[x]-dep[y];
        for(int i=0;i<18;i++)    if(len>>i&1)
            x=f[x][i];
        if(x==y)    return x;
        for(int i=17;~i;i--)    if(f[x][i]!=f[y][i])
            x=f[x][i],y=f[y][i];
        //assert(x>1&&y>1);
        return f[x][0];
    }
    struct node{int sum,ls,rs;}t[N*80];
    int poi,n,c[N],id[N];
    set<int> cc[N]; int rt[N];
    void insert(int x,int &y,int l,int r,int p,int v)
    {
        y=++poi; t[y]=t[x]; t[y].sum+=v;
        if(l==r)    return; int mid=l+r>>1;
        if(p<=mid)    insert(t[x].ls,t[y].ls,l,mid,p,v);
        else    insert(t[x].rs,t[y].rs,mid+1,r,p,v);
    }
    int query(int x,int l,int r,int LL,int RR)
    {
        if(!x || (LL<=l&&RR>=r))    return t[x].sum;
        int mid=l+r>>1,ans=0;
        if(LL<=mid)    ans+=query(t[x].ls,l,mid,LL,RR);
        if(RR>mid)    ans+=query(t[x].rs,mid+1,r,LL,RR);
        return ans;
    }
    void clear()
    {
        memset(rt,0,n+1<<2);
        memset(in,0,n+1<<2);
        cnt=tms=poi=0;
        for(int i=1;i<=n;i++)
            cc[i].clear();
    }
    bool azy(int a,int b){return dep[a]<dep[b];}
    void solve()
    {
        clear(); int lastans=0;
        n=read(); int q=read(),ff,mxd=0;
        for(int i=1;i<=n;i++)
            c[i]=read(),id[i]=i;
        for(int i=2;i<=n;i++)    ff=read(),add(ff,i);
        dep[1]=1; dfs(1); sort(id+1,id+n+1,azy);
        for(int i=1;i<=n;i++)
        {
            int x=id[i],lst=0,nxt=0,cl=c[x],dd=dep[x],gg=dep[id[i-1]];
            mxd=max(mxd,dep[x]);// assert(x);
            IT ls=cc[cl].lower_bound(dfn[x]),
               nx=cc[cl].upper_bound(dfn[x]);
            insert(rt[gg],rt[dd],1,n,dfn[x],1);
            if(ls!=cc[cl].begin())
            {
                lst=idfn[*(--ls)];
                insert(rt[dd],rt[dd],1,n,dfn[LCA(lst,x)],-1);
            }
            if(nx!=cc[cl].end())
            {
                nxt=idfn[*nx];
                insert(rt[dd],rt[dd],1,n,dfn[LCA(nxt,x)],-1);
            }
            if(lst&&nxt)
                insert(rt[dd],rt[dd],1,n,dfn[LCA(nxt,lst)],1);
            cc[cl].insert(dfn[x]);
        }
        while(q--)
        {
            int x=read()^lastans,d=read()^lastans;
            //assert(x<=n);
            printf("%d
    ",lastans=query(rt[min(dep[x]+d,mxd)],1,n,dfn[x],dfn[x]+sz[x]-1));
        }
    }
    int main()
    {
        int T=read();
        while(T--)
            solve();
        return 0;
    }
    View Code
  • 相关阅读:
    浅析Java中 new 和不 new 对象的区别
    uniapp打包后提示本应用使用HBuilderX 3.1.12 或对应的cli版本编译,而手机端SDK版本是3.1.13,不匹配的版本可能造成应用异常的解决办法
    浅析端口被占用如何做、windows报错'telnet'不是内部或外部命令,也不是可运行的程序如何处理
    苹果审核不过出现"您的 App 包含 NSUserTrackingUsageDescription...."解决办法
    CSS知识点:text-align-last段落最后一行设置对齐方式、transform:rotateY()翻转
    [转]scrollHeight, clientHeight, offsetHeight的区别
    【转】CSS变量(自定义属性)实践指南
    【转】angular 自定义 component decorator
    【转】Angular 编译打包 & Docker发布
    Angular FormControl Example | Angular 9 FormControl (理解angular formControl)
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/11648728.html
Copyright © 2020-2023  润新知