您的位置:首页 > 其它

2017.9.14 dispatching 思考记录

2017-09-14 00:36 190 查看
看发表时间不知道的以为是美国人

这个题是要求出一个点作为管理,那我们就可以枚举这个点

然后再在他的子树中从小到大累加,统计个数,知道>m为止

由于涉及到维护大小、这种大小关系的合并,所以我们考虑splay以及splay启发式合并

于是就用splay维护size、点的花费,splay子树的花费和

注意空间重复利用,不然开销是nlogn的,会mle

没卡nlog^2n十分良心

splay好久没写凭感觉打竟然是对的

听说左偏树或斜堆几十行就搞定了、但对于熟悉splay的玩家来说应该写splay会比较稳?反正我不熟

注意:splay上找的时候一定注意全面

注意几个if之间有没有else

码:

#include<iostream>
#include<cstdio>
using namespace std;
#include<cstring>
#define N 100005
int c
,v1
,n,sz[1000009],ch[1000009][2],fu
,rt
,cnt,m,tot,hou[N<<1],xia
,zhong[N<<1];
long long ans,vv[1000009],v[1000009];
void up(int o)
{
vv[o]=vv[ch[o][0]]+vv[ch[o][1]]+v[o];
sz[o]=sz[ch[o][0]]+sz[ch[o][1]]+1;
}
void set(int o,int wh,int t)
{
ch[o][wh]=t;
if(t!=0)fu[t]=o;
up(o);
}
int getwh(int o)
{
return ch[fu[o]][1]==o;
}
void rotate(int o)
{
int fa=fu[o],ye=fu[fu[o]];
int wh=getwh(o);
set(fa,wh,ch[o][wh^1]);
set(o,wh^1,fa);
fu[o]=ye;
if(ye!=0) ch[ye][ch[ye][1]==fa?1:0]=o;
}
void splay(int o,int tar,int z)
{
for(;fu[o]!=tar;rotate(o))
if(fu[fu[o]]!=0)
getwh(fu[o])==getwh(o)?rotate(fu[o]):rotate(o);
if(tar==0)rt[z]=o;
}
void ins(int o,int val,int yy)
{
int lin=o;
if(yy==0)
{
sz[++cnt]=1;
v[cnt]=val;
vv[cnt]=val;
sz[cnt]=1;
yy=cnt;
}else
{
vv[yy]=v[yy];
sz[yy]=1;
ch[yy][0]=ch[yy][1]=0;
fu[yy]=0;
}
o=rt[o];
int last=0;
while(o!=0)
{
last=o;
if(val<=v[o])o=ch[o][0];
else o=ch[o][1];
}
if(last==0)
{
rt[lin]=o;
return;
}
if(v[last]<val)set(last,1,yy);
else set(last,0,yy);
splay(yy,0,lin);
}
int cha(int o)
{
int ys=m;
o=rt[o];
int ans=0;
while(o)
{
if(vv[ch[o][0]]+v[o]==ys)
{
ans+=sz[ch[o][0]]+1;
break;
}else
if(vv[ch[o][0]]+v[o]>ys)
{
o=ch[o][0];
}else
if(vv[ch[o][0]]+v[o]<ys)
{
ans+=sz[ch[o][0]]+1;
ys-=vv[ch[o][0]]+v[o];
o=ch[o][1];
}
}
return ans;
}
void jian(int a,int b)
{
++tot,hou[tot]=xia[a],xia[a]=tot,zhong[tot]=b;
}
void jia(int a,int b)
{
jian(a,b);
jian(b,a);
}
void bianli(int o,int mb)
{
if(o==0)return;
bianli(ch[o][0],mb);
bianli(ch[o][1],mb);
ins(mb,v[o],o);

}
int js;
void dfs(int o,int fa)
{
++js;
int i;
++cnt;
rt[o]=cnt;
v[cnt]=c[o];
sz[cnt]=1;
vv[cnt]=c[o];
for(i=xia[o];i!=-1;i=hou[i])
{
int nd=zhong[i];
if(nd==fa)continue;
dfs(nd,o) ;
if(sz[rt[o]]>sz[rt[nd]])
{
bianli(rt[nd],o);
}else
{
bianli(rt[o],nd);
rt[o]=rt[nd];
}
}
ans=max(ans,1ll*cha(o)*1ll*v1[o]);
}
int main()
{
int i,x;
memset(xia,-1,sizeof(xia));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&c[i],&v1[i]);
if(x!=0)jia(x,i);
}
dfs(1,1);
printf("%lld",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: