BZOJ2809 dispatching 【可并堆】
题目分析:
yy一下就知道了,合并用可并堆少个log。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 102000; 5 6 int n,m; 7 int b[maxn],c[maxn],l[maxn],sz[maxn]; 8 long long tot[maxn]; 9 int dis[maxn],val[maxn],ch[maxn][2],pts[maxn]; 10 vector <int> g[maxn]; 11 long long ans = 0; 12 13 int merge(int r1,int r2){ 14 if(r1 == 0) return r2; if(r2 == 0) return r1; 15 if(val[r1] > val[r2]){ 16 ch[r1][1] = merge(ch[r1][1],r2); 17 if(dis[ch[r1][0]] < dis[ch[r1][1]]) swap(ch[r1][0],ch[r1][1]); 18 if(ch[r1][1]) dis[r1] = dis[ch[r1][1]] + 1; 19 else dis[r1] = 0; 20 return r1; 21 }else{ 22 ch[r2][1] = merge(r1,ch[r2][1]); 23 if(dis[ch[r2][0]] < dis[ch[r2][1]]) swap(ch[r2][0],ch[r2][1]); 24 if(ch[r2][1]) dis[r2] = dis[ch[r2][1]] + 1; 25 else dis[r2] = 0; 26 return r2; 27 } 28 } 29 30 void read(){ 31 scanf("%d%d",&n,&m); 32 for(int i=1;i<=n;i++) scanf("%d%d%d",&b[i],&c[i],&l[i]); 33 for(int i=1;i<=n;i++){g[b[i]].push_back(i);} 34 } 35 36 void dfs(int now){ 37 for(int i=0;i<g[now].size();i++){ 38 dfs(g[now][i]); 39 sz[now] += sz[g[now][i]]; 40 tot[now] += tot[g[now][i]]; 41 } 42 sz[now]++; tot[now] += c[now]; 43 for(int i=0;i<g[now].size();i++)pts[now]=merge(pts[now],pts[g[now][i]]); 44 while(tot[now] > m){ 45 tot[now] -= val[pts[now]];sz[now]--; 46 pts[now] = merge(ch[pts[now]][0],ch[pts[now]][1]); 47 } 48 ans = max(ans,1ll*l[now]*sz[now]); 49 } 50 51 void work(){ 52 for(int i=1;i<=n;i++) pts[i] = i,val[i] = c[i]; 53 dfs(g[0][0]); 54 printf("%lld",ans); 55 } 56 57 int main(){ 58 read(); 59 work(); 60 return 0; 61 }