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

    description

    vjudge
    给定一棵(n)点的树,每个节点上有一个颜色,每次询问一个点的子树中与这个点距离不超过(d)的点的颜色有多少种。强制在线。
    ——本题面描述转载租酥雨的博客,版权所有,仿冒必究

    data range

    [sum n,sum mle 5 imes 10^5 ]

    solution

    考虑线段树合并。
    首先想到维护深度的线段树,处理出每个节点对应深度最前的颜色有多少个。
    合并时可能会算重,如果直接维护不知道颜色的重复情况,
    所以还要维护一棵颜色的线段树,记录每个颜色的最浅深度
    因为这里的每一棵线段树都要用于查询,因此合并时不能向主席树那样直接指儿子,而要新建节点

    复杂度(O(nlogn))

    Code

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cassert>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define FL "a"
    #define fi first
    #define se second
    #define RG register
    using namespace std;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-6;
    const int mod=1e4;
    const int N=4e5+10;
    const int M=4e5+10;
    const dd pi=acos(-1);
    const int inf=2147483647;
    const ll INFL=1e18+1;
    const ll P=100000;
    inline ll read(){
      RG ll data=0,w=1;RG char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
      if(ch=='-')w=-1,ch=getchar();
      while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
      return data*w;
    }
    inline void file(){
      srand(time(NULL)+rand());
      freopen(FL".in","r",stdin);
      freopen(FL".out","w",stdout);
    }
    
    int n,m,c[N],ans;
    int head[N],nxt[N<<1],to[N<<1],cnt;
    inline void add(int u,int v){to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;}
    
    int drt[N],ds[2][20*N],sz[20*N],dtot;
    #define mid ((l+r)>>1)
    void dinsert(int &i,int l,int r,int p,int v){//sum of colors
      int x=++dtot;ds[0][x]=ds[0][i];ds[1][x]=ds[1][i];sz[x]=sz[i]+v;i=x;
      if(l==r)return;
      p<=mid?dinsert(ds[0][i],l,mid,p,v):dinsert(ds[1][i],mid+1,r,p,v);
    }
    int query(int i,int l,int r,int x,int y){
      if(!i||x>y)return 0;if(x<=l&&r<=y)return sz[i];int v=0;
      if(x<=mid)v=query(ds[0][i],l,mid,x,y);
      if(mid<y)v+=query(ds[1][i],mid+1,r,x,y);
      return v;
    }
    int dmerge(int a,int b){
      if(!a||!b)return a|b;int c=++dtot;
      ds[0][c]=dmerge(ds[0][a],ds[0][b]);
      ds[1][c]=dmerge(ds[1][a],ds[1][b]);
      sz[c]=sz[a]+sz[b];return c;
    }
    
    int crt[N],cs[2][20*N],mn[20*N],ctot;
    void cinsert(int &i,int l,int r,int p,int v){//mindep of color
      if(!i){i=++ctot;mn[i]=inf;cs[0][i]=cs[1][i]=0;}
      mn[i]=min(mn[i],v);if(l==r)return;
      p<=mid?cinsert(cs[0][i],l,mid,p,v):cinsert(cs[1][i],mid+1,r,p,v);
    }
    int cmerge(int a,int b,int l,int r,int u){
      if(!a||!b)return a|b;int c=++ctot;
      if(l==r){
        dinsert(drt[u],1,n,max(mn[a],mn[b]),-1);
        mn[c]=min(mn[a],mn[b]);cs[0][c]=cs[1][c]=0;
      }
      else{
        cs[0][c]=cmerge(cs[0][a],cs[0][b],l,mid,u);
        cs[1][c]=cmerge(cs[1][a],cs[1][b],mid+1,r,u);
        mn[c]=min(mn[cs[0][c]],mn[cs[1][c]]);
      }
      return c;
    }
    
    int dep[N];
    void dfs(int u){
      for(RG int i=head[u];i;i=nxt[i]){
        RG int v=to[i];dfs(v);
        crt[u]=cmerge(crt[u],crt[v],1,n,u);
        drt[u]=dmerge(drt[u],drt[v]);
      }
    }
    
    int main()
    {
      int T=read();
      while(T--){
        n=read();m=read();
        ans=ctot=dtot=cnt=0;dep[1]=1;mn[0]=inf;
        for(RG int i=1;i<=n;i++)head[i]=crt[i]=drt[i]=0,c[i]=read();
        for(RG int i=2,fa;i<=n;i++)fa=read(),add(fa,i),dep[i]=dep[fa]+1;
        for(RG int i=1;i<=n;i++){
          dinsert(drt[i],1,n,dep[i],1);
          cinsert(crt[i],1,n,c[i],dep[i]);
        }
        dfs(1);
        for(RG int i=1,u,d;i<=m;i++){
          u=read()^ans;d=dep[u]+(read()^ans);
          ans=query(drt[u],1,n,1,min(d,n));printf("%d
    ",ans);
        }
      }
      return 0;
    }
    
    
  • 相关阅读:
    toj 2819 Travel
    toj 2807 Number Sort
    zoj 2818 Prairie dogs IV
    zoj 1276 Optimal Array Multiplication Sequence
    toj 2802 Tom's Game
    toj 2798 Farey Sequence
    toj 2815 Searching Problem
    toj 2806 Replace Words
    toj 2794 Bus
    css截取字符
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9919326.html
Copyright © 2011-2022 走看看