【bzoj2599】: [IOI2011]Race

来源:互联网 发布:淘宝宝贝复制破解 编辑:程序博客网 时间:2024/06/06 01:04

大概没人像我这么脑残写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;}
0 0
原创粉丝点击