大概没人像我这么脑残写splay 一开始正常的splay其中一个点跑了100m 然后加了splay(rand())就神奇的过了
神奇的splay233333333333333
233333333333其实并不是这样 只有保证每次访问到的最深的点都被splay到根splay的复杂度才能保证
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=400011;
const int inf=0x3f3f3f3f;
int head[N],next[N],key[N],w[N],tot;
int size[N],mx[N],sum,root,rt;
int dist[N],dep[N];
int vis[N],ans=inf,cnt,k;
struct node
{int l,r,fa,gs,d,dep;}sp[N];
void add(int x,int y,int z)
{
tot++;
next[tot]=head[x];
head[x]=tot;
key[tot]=y;
w[tot]=z;
}
void zig(int x)
{
int y=sp[x].fa;
sp[y].l=sp[x].r;
if(sp[x].r)sp[sp[x].r].fa=y;
sp[x].fa=sp[y].fa;
if(sp[y].fa)
if(sp[sp[y].fa].l==y)sp[sp[y].fa].l=x;
else sp[sp[y].fa].r=x;
sp[x].r=y,sp[y].fa=x;
}
void zag(int x)
{
int y=sp[x].fa;
sp[y].r=sp[x].l;
if(sp[x].l)sp[sp[x].l].fa=y;
sp[x].fa=sp[y].fa;
if(sp[y].fa)
if(sp[sp[y].fa].l==y)sp[sp[y].fa].l=x;
else sp[sp[y].fa].r=x;
sp[x].l=y,sp[y].fa=x;
}
void splay(int x,int aim)
{
while(sp[x].fa!=aim)
{
int y=sp[x].fa;
if(sp[y].fa==aim)
{
if(sp[y].l==x)zig(x);
else zag(x);
}
else
{
if(sp[sp[y].fa].l==y)
{
if(sp[y].l==x)zig(y),zig(x);
else zag(x),zig(x);
}
else
{
if(sp[y].r==x)zag(y),zag(x);
else zig(x),zag(x);
}
}
}
if(aim==0)rt=x;
}
int judge(int x,int d)//权值为d的数是否存在
{
if(x==0)return -1;
int l=sp[x].l,r=sp[x].r;
if(sp[x].d>d)return judge(l,d);
if(sp[x].d==d)return sp[x].dep;
return judge(r,d);
}
int find(int x,int d,int ret)//小于等于d的第一个位置
{
if(x==0)return ret;
int l=sp[x].l,r=sp[x].r;
if(sp[x].d>d)return find(l,d,ret);
if(sp[x].d==d)return x;
return find(r,d,x);
}
int getnext(int x)
{
x=sp[x].r;
while(sp[x].l)x=sp[x].l;
return x;
}
void insert(int d,int dep)
{
int x=find(rt,d,0);
if(sp[x].d==d)
{
sp[x].gs++;
sp[x].dep=min(sp[x].dep,dep);
return;
}
splay(x,0);
int y=getnext(x);
splay(y,x);
sp[y].l=++cnt;
sp[cnt].l=sp[cnt].r=0;
sp[cnt].d=d;
sp[cnt].gs=1;
sp[cnt].fa=y;
sp[cnt].dep=dep;
}
void getsize(int x,int fa)
{
size[x]=1,mx[x]=0;
for(int i=head[x];i;i=next[i])
{
int y=key[i];
if(vis[y]==0&&y!=fa)
{
getsize(y,x);
size[x]+=size[y];
mx[x]=max(mx[x],size[y]);
}
}
mx[x]=max(mx[x],sum-size[x]);
if(mx[x]<mx[root])root=x;
}
void getdist(int x,int fa)
{
//splay(rand()%cnt+1,0);
int tmp=judge(rt,k-dist[x]);
if(tmp!=-1)ans=min(ans,dep[x]+tmp);
if(tmp!=-1)splay(tmp,0);
else splay(find(rt,k-dist[x],0),0);
for(int i=head[x];i;i=next[i])
{
int y=key[i];
if(y!=fa&&vis[y]==0)
{
dist[y]=dist[x]+w[i];
dep[y]=dep[x]+1;
getdist(y,x);
}
}
}
void slove(int x,int fa)
{
insert(dist[x],dep[x]);
for(int i=head[x];i;i=next[i])
{
int y=key[i];
if(y!=fa&&vis[y]==0)
slove(y,x);
}
}
void bili()
{
cnt=2;rt=1;
sp[1].l=2;sp[1].r=0;
sp[2].l=sp[2].r=0;
sp[1].d=inf;sp[2].d=-inf;
sp[2].fa=1;sp[1].fa=0;
insert(0,0);
}
void debug(int x)
{
if(x==0)return;
debug(sp[x].l);
cout<<sp[x].d<<" ";
debug(sp[x].r);
}
void dfs(int now)
{
root=0;
getsize(now,-1);
vis[root]=1;
insert(0,0);
for(int i=head[root];i;i=next[i])
{
int y=key[i];
if(!vis[y])
{
dist[y]=w[i];
dep[y]=1;
getdist(y,root);
slove(y,root);
}
}
for(int i=head[root];i;i=next[i])
{
int y=key[i];
if(!vis[y])
{
sum=size[y];
bili();
dfs(y);
}
}
}
int main()
{
// freopen("race48.in","r",stdin);
// freopen("race48.ans","w",stdout);
int n;
cin>>n>>k;
for(int i=1;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
x++,y++;
add(x,y,z);
add(y,x,z);
}
bili();
sum=n,mx[0]=inf;
dfs(1);
if(ans==inf)puts("-1");
else printf("%d\n",ans);
return 0;
}