[十二省联考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 }