[十二省联考2019]春节十二响

[十二省联考2019]春节十二响

好后悔考场没思考这道最良心的水题...t1花了我两个半点结果连20都拿不到

哭了

题目描述:略

思路:将一个点下面的几条链合并成一条

用长链剖分的话似乎可以简化操作

实在太水了所以没啥好说的...

 1 #include<cstdio>
 2 #include<queue>
 3 using std::priority_queue;
 4 typedef long long lint;
 5 const int N=200011;
 6 template<typename st> st max(st a,st b){return a>b?a:b;}
 7 int n;
 8 lint v[N];
 9 struct sumireko
10 {
11     int to,ne;
12 }e[N];
13 int he[N],ecnt;
14 void addline(int f,int t)
15 {
16     e[++ecnt].to=t;
17     e[ecnt].ne=he[f];
18     he[f]=ecnt;
19 }
20 int fa[N],len[N],top[N],dson[N];
21 void dfs1(int x)
22 {
23     len[x]=1;
24     for(int i=he[x],t;i;i=e[i].ne)
25     {
26         t=e[i].to;
27         if(t==fa[x]) continue;
28         dfs1(t);
29         if(len[t]>=len[x])
30         {
31             dson[x]=t;
32             len[x]=len[t]+1;
33         }
34     }
35 }
36 priority_queue<lint> q[N];
37 lint sta[N],hop;
38 void dfs2(int x,int tt)
39 {
40     top[x]=tt;
41     if(dson[x])
42     {
43         dfs2(dson[x],tt);
44         for(int i=he[x],t;i;i=e[i].ne)
45         {
46             t=e[i].to;
47             if(t==fa[x]||t==dson[x]) continue;
48             dfs2(t,t);
49             for(int j=1;j<=len[t];j++)
50             {
51                 lint a=q[tt].top(),b=q[t].top();
52                 q[tt].pop(),q[t].pop();
53                 sta[++hop]=max(a,b);
54             }
55             while(hop)
56             {
57                 q[tt].push(sta[hop--]);
58             }
59         }
60     }
61     q[tt].push(v[x]);
62 }
63 
64 int main()
65 {
66     scanf("%d",&n);
67     for(int i=1;i<=n;i++) scanf("%lld",&v[i]);
68     for(int i=2;i<=n;i++)
69     {
70         scanf("%d",&fa[i]);
71         addline(fa[i],i);
72     }
73     dfs1(1);
74     dfs2(1,1);
75     lint ans=0;
76     while(!q[1].empty())
77     {
78         ans+=q[1].top();
79         q[1].pop();
80     }
81     printf("%lld
",ans);
82     return 0;
83 }
原文地址:https://www.cnblogs.com/rikurika/p/10682703.html