解题:CF1009 Dominant Indices

题面

长链剖分模板题

只能按深度统计,同时比DSU on tree难理解一些,但是复杂度少个log

对每个点抓出向下延伸最长的儿子叫做长儿子。在合并时用指针继承信息,对于长儿子O(1)继承,其他儿子暴力

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=1000005;
 6 int len[N],imp[N],ans[N];
 7 int p[N],noww[2*N],goal[2*N];
 8 int mem[N],*pts[N],*fpt=mem+1;
 9 int n,t1,t2,cnt;
10 void Link(int f,int t)
11 {
12     noww[++cnt]=p[f];
13     goal[cnt]=t,p[f]=cnt;
14 }
15 void DFS(int nde,int fth,int dth)
16 {
17     for(int i=p[nde];i;i=noww[i])
18         if(goal[i]!=fth)
19         {
20             DFS(goal[i],nde,dth+1);
21             if(len[goal[i]]>len[imp[nde]])
22                 imp[nde]=goal[i];
23         }
24     len[nde]=len[imp[nde]]+1;
25 }
26 void Getans(int nde,int fth)
27 {
28     pts[nde][0]=1;
29     if(imp[nde])
30     {
31         pts[imp[nde]]=pts[nde]+1;
32         Getans(imp[nde],nde),ans[nde]=ans[imp[nde]]+1;
33     }
34     for(int i=p[nde];i;i=noww[i])
35         if(goal[i]!=fth&&goal[i]!=imp[nde])
36         {
37             pts[goal[i]]=fpt,fpt+=len[goal[i]],Getans(goal[i],nde);
38             for(int j=1;j<=len[goal[i]];j++)
39             {
40                 pts[nde][j]+=pts[goal[i]][j-1];
41                 int b1=(j<=ans[nde]&&pts[nde][j]>=pts[nde][ans[nde]]);
42                 int b2=(j>ans[nde]&&pts[nde][j]>pts[nde][ans[nde]]);
43                 if(b1||b2) ans[nde]=j;
44             }
45         }
46     if(pts[nde][ans[nde]]==1) ans[nde]=0;
47 }
48 int main()
49 {
50     scanf("%d",&n);
51     for(int i=1;i<n;i++)
52     {
53         scanf("%d%d",&t1,&t2); 
54         Link(t1,t2),Link(t2,t1);
55     }
56     DFS(1,0,0),pts[1]=fpt,fpt+=len[1];
57     Getans(1,0); 
58     for(int i=1;i<=n;i++)
59         printf("%d\n",ans[i]);
60     return 0;
61 }
View Code

猜你喜欢

转载自www.cnblogs.com/ydnhaha/p/10170599.html