CF1009F Dominant Indices

传送门

还是放个链接让泥萌去学一下把 orzYYB

题目中要求的\(f_{x,j}\),转移是\(f_{x,j}=\sum_{y=son_x} f_{y,j-1}\),所以这个东西可以用长链剖分优化,利用指针,每个点直接继承重儿子信息,轻儿子的话暴力合并,一边合并一边更新答案

#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register

using namespace std;
const int N=1e6+10;
il int rd()
{
  int x=0,w=1;char ch=0;
  while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
  while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  return x*w;
}
int to[N<<1],nt[N<<1],hd[N],dg[N],tot=1;
il void add(int x,int y)
{
  ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot,++dg[x];
  ++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot,++dg[y];
}
int n,m;
int ff[N],de[N],dpt[N],son[N];
int *f[N],rbq[N<<2],*uc=rbq+1,an[N];
void dfs1(int x)
{
  dpt[x]=de[x];
  for(int i=hd[x];i;i=nt[i])
    {
      int y=to[i];
      if(y==ff[x]) continue;
      ff[y]=x,de[y]=de[x]+1,dfs1(y),dpt[x]=max(dpt[x],dpt[y]);
      if(dpt[son[x]]<dpt[y]) son[x]=y;
    }
}
void dd(int x)
{
  f[x][0]=1;
  if(son[x]) f[son[x]]=f[x]+1,dd(son[x]),an[x]=f[son[x]][an[son[x]]]>1?an[son[x]]+1:0;
  for(int i=hd[x];i;i=nt[i])
    {
      int y=to[i];
      if(y==ff[x]||y==son[x]) continue;
      f[y]=uc,uc+=(dpt[y]-de[x]+1);
      dd(y);
      for(int j=0;j<dpt[y]-de[x]+1;++j) f[x][j+1]+=f[y][j];
      for(int j=0;j<dpt[y]-de[x]+1;++j)
        if(f[x][j+1]>f[x][an[x]]||(f[x][j+1]==f[x][an[x]]&&j+1<an[x])) an[x]=j+1;
    }
}

int main()
{
  n=rd();
  for(int i=1;i<n;++i) add(rd(),rd());
  de[1]=1,dfs1(1);
  f[1]=uc,uc+=dpt[1]+1;
  dd(1);
  for(int i=1;i<=n;i++) printf("%d\n",an[i]);
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/smyjr/p/10070052.html