APIO题。。。我是拿左偏树做的。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define maxv 100500 #define maxe 100500 using namespace std; long long n,m,tree[maxv][3],fath[maxv],g[maxv],nume=0,size[maxv],val[maxv],dis[maxv]; long long a,b,c,w[maxv],q[maxv],ans=0,top[maxv]; struct edge { long long v,nxt; }e[maxe]; void addedge(long long u,long long v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } void pushup(long long x) { long long ls=tree[x][1],rs=tree[x][2]; if (dis[ls]<dis[rs]) swap(tree[x][1],tree[x][2]); if (rs==0) dis[x]=0; else dis[x]=dis[rs]+1; size[x]=size[ls]+size[rs]+1; val[x]=val[ls]+val[rs]+w[x]; } long long merge(long long a,long long b) { if (a==0) return b; if (b==0) return a; if (w[a]<w[b]) swap(a,b); tree[a][2]=merge(tree[a][2],b); pushup(a); return a; } long long pop(long long x) { long long ls=tree[x][1],rs=tree[x][2]; fath[ls]=ls;fath[rs]=rs; tree[x][1]=0;tree[x][2]=0;size[x]=1;val[x]=w[x];dis[x]=0; return merge(ls,rs); } void dfs(long long now) { long long regis=now; for (long long i=g[now];i;i=e[i].nxt) { long long v=e[i].v; dfs(v); } for (long long i=g[now];i;i=e[i].nxt) { long long v=e[i].v; regis=merge(regis,top[v]); } while (val[regis]>m) regis=pop(regis); top[now]=regis; ans=max(ans,size[regis]*q[now]); } int main() { scanf("%lld%lld",&n,&m); for (long long i=1;i<=n;i++) { scanf("%lld%lld%lld",&a,&b,&c); if (a) addedge(a,i); w[i]=b;q[i]=c; } for (long long i=1;i<=n;i++) { fath[i]=i; val[i]=w[i]; size[i]=1; top[i]=i; } dfs(1); printf("%lld\n",ans); return 0; }
时间: 2024-10-31 22:24:28