• 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  } 
  • 相关阅读:
    java语言实现堆排序
    堆排序
    静态分派
    谈mysql优化
    Unity2017.1官方UGUI文档翻译——Canvas
    Unity2017.1官方UGUI文档翻译——Rect Transform
    Unity2017.1官方UGUI文档翻译——Rich Text
    Unity2017.1官方UGUI文档翻译——Auto Layout
    Unity2017.1官方UGUI文档翻译——Animation Integration
    Unity2017.1官方UGUI文档翻译——Interaction Components
  • 原文地址:https://www.cnblogs.com/wanglichao/p/7184594.html
Copyright © 2020-2023  润新知