bzoj2809: [Apio2012]dispatching 启发式合并splay
/************************************************************** Problem: 2809 User: wangyucheng Language: C++ Result: Accepted Time:5432 ms Memory:88556 kb ****************************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> typedef long long ll; using namespace std; #define N 1100000 #define inf 0x6ffffffffffffffLL int ch[N][2],siz[N],pre[N]; ll val[N],sum[N]; int rank[N]; int e[N],ne[N*2],v[N*2]; int b[N],nn,n; ll m; ll L[N],c[N]; void add(int x,int y){ ne[++nn]=e[x],e[x]=nn,v[nn]=y; } void up(int x){ siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+val[x]; } void rotate(int x){ int y=pre[x],z=pre[y],k=(ch[y][0]==x); pre[ch[y][!k]=ch[x][k]]=y; pre[ch[x][k]=y]=x; pre[x]=z; if(z)ch[z][ch[z][1]==y]=x; up(y); } void splay(int x,int fa){ for(;pre[x]!=fa;){ int y=pre[x],z=pre[y]; if(z==fa)rotate(x); else if((ch[z][1]==y)==(ch[y][1]==x))rotate(y),rotate(x); else rotate(x),rotate(x); } up(x); } int select(int x,int k){ while(siz[ch[x][0]]+1!=k){ if(k>siz[ch[x][0]]){ k-=siz[ch[x][0]]+1; x=ch[x][1]; }else x=ch[x][0]; } splay(x,0); return x; } int cha(int x,int y){ int now=x,k; while(1){ k=(val[x]<val[y]); if(!ch[x][k]){ ch[y][0]=0,ch[y][1]=0; sum[y]=val[y]; siz[y]=1; ch[x][k]=y; pre[y]=x; splay(y,0); break; }else x=ch[x][k]; } return y; } int qu[N],bo,he; int e1; void bing(int x,int y){ splay(x,0),splay(y,0); if(siz[x]<siz[y])swap(x,y); for(qu[bo=he=1]=y;he>=bo;bo++){ e1=qu[bo]; if(ch[e1][0])qu[++he]=ch[e1][0]; if(ch[e1][1])qu[++he]=ch[e1][1]; } for(int i=1;i<=he;i++)x=cha(x,qu[i]); } ll ans; void dfs(int x){ int p=x; for(int i=e[x];i;i=ne[i]){ dfs(v[i]); bing(v[i],x); } splay(x,0); int l=0,r=siz[x]+1,mid; while(l+1!=r){ mid=(l+r)>>1; x=select(x,mid); if(sum[ch[x][0]]+val[x]>m)r=mid; else l=mid; } ans=max(ans,(ll)l*L[p]); } int main(){ scanf("%d%lld",&n,&m); for(int i=1;i<=n;i++){ scanf("%d%lld%lld",&b[i],&c[i],&L[i]); if(b[i])add(b[i],i); } for(int i=1;i<=n;i++){ siz[i]=1,sum[i]=val[i]=c[i]; } dfs(1); cout<<ans; }