zoukankan      html  css  js  c++  java
  • HDU5709 Claris Loves Painting

    题目
    建两棵动态开点权值线段树。
    一棵以颜色为下标,维护每种颜色出现的最浅深度。
    一棵以深度为下标,维护以该深度为最浅深度的颜色有多少种。
    然后dfs的时候启发式合并线段树即可。

    #include<bits/stdc++.h>
    #define mid ((l+r)>>1)
    #define pb push_back
    using namespace std;
    namespace IO
    {
        char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
        char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
        void Flush(){fwrite(obuf,1,oS-obuf,stdout),oS=obuf;}
        void Put(char x){*oS++=x;if(oS==oT)Flush();}
        int read(){int x=0;char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
        void write(int x){int top=0;if(!x)Put('0');while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put('
    ');}
    }
    using namespace IO;
    int min(int a,int b){return a<b? a:b;}
    int max(int a,int b){return a>b? a:b;}
    const int N=100007;
    int col[N],nxt[N],head[N],root1[N],root2[N],dep[N],ans,n,m,cnt;
    struct node{int l,r,x;}t[N*100];
    vector<int>G[N];
    void build(int &p,int l,int r,int x,int v)
    {
        p=++cnt;
        if(l==r) return t[p].x=v,void();
        x<=mid? build(t[p].l,l,mid,x,v):build(t[p].r,mid+1,r,x,v);
    }
    void update(int &p,int l,int r,int x,int v)
    {
        t[++cnt]=t[p],t[p=cnt].x+=v;
        if(l==r) return ;
        x<=mid? update(t[p].l,l,mid,x,v):update(t[p].r,mid+1,r,x,v);
    }
    int query(int p,int l,int r,int L,int R)
    {
        if(L<=l&&r<=R) return t[p].x;
        return (L<=mid? query(t[p].l,l,mid,L,R):0)+(R>mid? query(t[p].r,mid+1,r,L,R):0);
    }
    int merge1(int u,int v,int l,int r,int x)
    {
        if(!u||!v) return u|v;
        int p=++cnt;
        if(l==r) t[p].x=min(t[u].x,t[v].x),update(root2[x],1,n,max(t[u].x,t[v].x),-1);
        t[p].l=merge1(t[u].l,t[v].l,l,mid,x),t[p].r=merge1(t[u].r,t[v].r,mid+1,r,x);
        return p;
    }
    int merge2(int u,int v)
    {
        if(!u||!v) return u|v;
        int p=++cnt;
        t[p]=(node){merge2(t[u].l,t[v].l),merge2(t[u].r,t[v].r),t[u].x+t[v].x};
        return p;
    }
    void dfs(int u)
    {
        build(root1[u],1,n,col[u],dep[u]),update(root2[u],1,n,dep[u],1);
        for(int i=0,v;i<G[u].size();++i) dep[v=G[u][i]]=dep[u]+1,dfs(v),root1[u]=merge1(root1[u],root1[v],1,n,u),root2[u]=merge2(root2[u],root2[v]);
    }
    int main()
    {
        for(int T=read(),i,x,d,ans;T;--T)
        {
            n=read(),m=read(),ans=0;
            for(i=1;i<=cnt;++i) t[i]=(node){0,0,0};
            for(cnt=0,i=1;i<=n;++i) col[i]=read(),root1[i]=root2[i]=0,G[i].clear();
            for(i=2;i<=n;++i) x=read(),G[x].pb(i);
            dep[1]=1;dfs(1);
            while(m--) x=read()^ans,d=read()^ans,write(ans=query(root2[x],1,n,dep[x],dep[x]+d));
        }
        return Flush(),0;
    }
    
  • 相关阅读:
    代码互改
    第一次个人编程作业
    第一次博客
    个人总结
    第三次个人作业--用例图设计
    第二次结对作业
    第一次结对作业
    记录浏览他人代码
    中文编程作业
    第一篇随笔
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11558065.html
Copyright © 2011-2022 走看看