zoukankan      html  css  js  c++  java
  • hdu5709Claris Loves Painting主席树 奇妙的DFS序

    先不考虑层数限制

    一棵树上每个点有个颜色,问一棵子树的颜色数

    感觉简单多了是吧

    考虑每个点的贡献:自己到根的路径上的一个包含自己的连续段

    观察最顶端的点的父亲:

    它满足有了额外的同色孩子(咦)

    这一条链上需要+1(@miaom)

    如果差分,就是在这个点+1(@miaom),在最近的有同色孩子的父亲-1,求子树和

    最近的有同色孩子的父亲?

    根据直觉,它一定是dfs序上和这个点相邻的同色点和这个点的lca

    没了

    再加上层数限制

    相当于一定要在一定的深度以内

    所以开主席树保持可持久化(怎么不能离线啊,好烦啊)

      1 #include <bits/stdc++.h>
      2 #define LOG 19
      3 #define mid (l+r>>1)
      4 using namespace std;
      5 int NODE,n,m,p,q,E,TIME,x,d;
      6 int dep[200001],nex[500001],fir[200001],Fir[200001],Nex[500001];
      7 int fa[200001][20],to[500001];//,ne[200001];
      8 int tr[8000001],ls[8000001],rs[8000001];
      9 int c[200001],root[200001],start[200001],en[200001],pos[200001];
     10 void dfs(int now,int fat)
     11 {
     12     dep[now]=dep[fat]+1;start[now]=++TIME;pos[TIME]=now;
     13     Nex[now]=Fir[dep[now]];Fir[dep[now]]=now;
     14     fa[now][0]=fat;
     15     for(int i=1;fa[now][i-1];i++) fa[now][i]=fa[fa[now][i-1]][i-1];
     16     for(int i=fir[now];i;i=nex[i])
     17     if(to[i]!=fat)
     18         dfs(to[i],now);
     19     en[now]=TIME;
     20 }
     21 int lca(int x,int y)
     22 {
     23     if(dep[x]<dep[y]) swap(x,y);
     24     for(int delta=dep[x]-dep[y],i=0;delta;delta>>=1,++i)
     25         if(delta&1) x=fa[x][i];
     26     for(int i=LOG;i>=0;i--)
     27         if(fa[x][i]!=fa[y][i])
     28             x=fa[x][i],y=fa[y][i];
     29     return (x==y)?x:fa[x][0];
     30 }
     31 int chan(int acc,int l,int r,int x,int y)
     32 {
     33     int now=++NODE;
     34     if(l==r)
     35     {
     36         tr[now]=tr[acc]+y;
     37         return now;
     38     }
     39     if(x<=mid) ls[now]=chan(ls[acc],l,mid,x,y),rs[now]=rs[acc];
     40     else rs[now]=chan(rs[acc],mid+1,r,x,y),ls[now]=ls[acc];
     41     tr[now]=tr[ls[now]]+tr[rs[now]];
     42     return now;
     43 }
     44 void add(int x,int y)
     45 {
     46     to[++E]=y;nex[E]=fir[x];fir[x]=E;
     47 }
     48 int que(int now,int l,int r,int x,int y)
     49 {
     50     if(l==x && r==y)
     51         return tr[now];
     52     int ret=0;
     53     if(x<=mid)
     54         ret+=que(ls[now],l,mid,x,min(y,mid));
     55     if(y>mid)
     56         ret+=que(rs[now],mid+1,r,max(mid+1,x),y);
     57     return ret;
     58 }
     59 set<pair<int,int> > se;
     60 int main()
     61 {
     62 int T;
     63 for(scanf("%d",&T);T;T--)
     64 {
     65     scanf("%d%d",&n,&m);E=0;TIME=0;NODE=0;
     66     se.clear();
     67     for(int i=1;i<=n;i++)
     68         scanf("%d",&c[i]);
     69     for(int i=1;i<=n;i++)
     70         fir[i]=0,Fir[i]=0;
     71     for(int i=1;i<=n;i++)
     72         for(int j=0;j<=19;j++)
     73             fa[i][j]=0;
     74     for(int i=1;i<n;i++)
     75         scanf("%d",&q),add(q,i+1);
     76     dfs(1,0);root[1]=1;tr[1]=0;ls[1]=0;rs[1]=0;
     77     int MD=0;
     78     for(int i=1;i<=n;root[i+1]=root[i],i++)
     79         for(int j=Fir[i];j;j=Nex[j])
     80         {
     81             int t=0;
     82             pair <int,int> tem=*se.lower_bound(make_pair(c[j],start[j])); 
     83             int tem1=tem.first;
     84             int Tem1=tem.second;
     85             if(tem1==c[j]) t=lca(pos[Tem1],j);
     86             if(se.lower_bound(make_pair(c[j],start[j]))!=se.begin())
     87             {
     88                 tem=*(--se.lower_bound(make_pair(c[j],start[j])));
     89                 int tem2=tem.first;
     90                 int Tem2=tem.second;
     91                 if(tem2==c[j] &&(!t || dep[t]<dep[lca(pos[Tem2],j)])) t=lca(pos[Tem2],j);
     92             }
     93             se.insert(make_pair(c[j],start[j]));
     94             if(t)
     95                 root[i]=chan(root[i],1,n,start[t],-1);
     96             root[i]=chan(root[i],1,n,start[j],1);
     97             MD=max(MD,i);
     98         }
     99     int lastans=0;
    100     for(int i=1;i<=m;i++)
    101     {
    102         if(i==2)
    103             int e=1;
    104         scanf("%d%d",&x,&d);
    105         x^=lastans;d^=lastans;
    106         int tim=min(dep[x]+d,MD);
    107         printf("%d
    ",lastans=que(root[tim],1,n,start[x],en[x]));
    108     }
    109 }
    110     return 0;
    111  } 
  • 相关阅读:
    LeetCode15 3Sum
    LeetCode10 Regular Expression Matching
    LeetCode20 Valid Parentheses
    LeetCode21 Merge Two Sorted Lists
    LeetCode13 Roman to Integer
    LeetCode12 Integer to Roman
    LeetCode11 Container With Most Water
    LeetCode19 Remove Nth Node From End of List
    LeetCode14 Longest Common Prefix
    LeetCode9 Palindrome Number
  • 原文地址:https://www.cnblogs.com/wanglichao/p/7184594.html
Copyright © 2011-2022 走看看