您的位置:首页 > 产品设计 > UI/UE

SPOJ 2798 Query on a tree again 树链剖分

2013-01-20 11:29 323 查看
这题真是神题!

当然我不是说这题有多神,而是你数组开小了和开大了得分不同,用不同版本的编译器得分不同。。。(数组没有越界的情况下)

呜呜。。。至今没有ac。一直83分。。。抑郁了。。。

跪求神犇指明错误。。。

View Code

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cstdio>

#define N 151000
#define M 251000
#define INF 1e9

using namespace std;

struct RT
{
int mn,zb;
}rt[N<<2];

int head
,to[M],next[M];
int tot,n,qu,cnt;
int fa
,son
,sz
,dep
,top
,q
;
int bh
,anbh
;

inline void add(int u,int v)
{
to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++;
}

inline void init()
{
memset(head,-1,sizeof head); cnt=0;
tot=0;
}

inline void prep()
{
int h=1,t=2,sta;
q[1]=1; dep[1]=1;
while(h<t)
{
sta=q[h++]; sz[sta]=1;
for(int i=head[sta];~i;i=next[i])
if(to[i]!=fa[sta])
{
fa[to[i]]=sta;
dep[to[i]]=dep[sta]+1;
q[t++]=to[i];
}
}
for(int j=t-1;j>=1;j--)
{
sta=q[j];
for(int i=head[sta];~i;i=next[i])
if(to[i]!=fa[sta])
{
sz[sta]+=sz[to[i]];
if(sz[to[i]]>sz[son[sta]]) son[sta]=to[i];
}
}
for(int i=1;i<t;i++)
{
sta=q[i];
if(son[fa[sta]]==sta) top[sta]=top[fa[sta]];
else top[sta]=sta;
}
}

inline void rewrite()
{
for(int i=1;i<=n;i++)
if(top[i]==i)
for(int j=i;j;j=son[j])
{
bh[j]=++tot;
anbh[tot]=j;
}
}

inline void pushup(int u)
{
if(rt[u<<1].mn<rt[u<<1|1].mn) rt[u]=rt[u<<1];
else rt[u]=rt[u<<1|1];
}

inline void build(int u,int L,int R)
{
if(L==R) {rt[u].mn=INF;rt[u].zb=L;return;}
int MID=(L+R)>>1;
build(u<<1,L,MID); build(u<<1|1,MID+1,R);
pushup(u);
}

inline void read()
{
init();
scanf("%d%d",&n,&qu);
for(int i=1,a,b;i<n;i++)
{
scanf("%d%d",&a,&b);
add(a,b); add(b,a);
}
prep();
rewrite();
build(1,1,tot);
}

inline int queryval(int u,int L,int R,int pos)
{
if(L==R) return rt[u].mn;
int MID=(L+R)>>1;
if(pos<=MID) return queryval(u<<1,L,MID,pos);
return queryval(u<<1|1,MID+1,R,pos);
}

inline void updata(int u,int L,int R,int pos,int val)
{
if(L==R) {rt[u].mn=val;return;}
int MID=(L+R)>>1;
if(pos<=MID) updata(u<<1,L,MID,pos,val);
else updata(u<<1|1,MID+1,R,pos,val);
pushup(u);
}

inline void change(int x)
{
int val=queryval(1,1,tot,bh[x]);
if(val==INF) updata(1,1,tot,bh[x],dep[x]);
else updata(1,1,tot,bh[x],INF);
}

inline RT querymin(int u,int L,int R,int l,int r)
{
if(l<=L&&R<=r) return rt[u];
int MID=(L+R)>>1; RT lp,rp; lp.mn=rp.mn=INF;
if(l<=MID) lp=querymin(u<<1,L,MID,l,r);
if(MID<r) rp=querymin(u<<1|1,MID+1,R,l,r);
if(lp.mn<rp.mn) return lp;
return rp;
}

inline void query(int x,int y)
{
RT tmp,res; res.mn=INF;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
tmp=querymin(1,1,tot,bh[top[x]],bh[x]);
if(tmp.mn<res.mn) res=tmp;
x=fa[top[x]];
}
if(bh[x]>bh[y]) swap(x,y);
tmp=querymin(1,1,tot,bh[x],bh[y]);
if(tmp.mn<res.mn) res=tmp;
if(res.mn!=INF) printf("%d\n",anbh[res.zb]);
else puts("-1");
}

inline void go()
{
int a,b;
while(qu--)
{
scanf("%d%d",&a,&b);
if(a==0) change(b);
else query(b,1);
}
}

int main()
{
read(),go();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: