SPOJ 2798 Query on a tree again 树链剖分
2013-01-20 11:29
323 查看
这题真是神题!
当然我不是说这题有多神,而是你数组开小了和开大了得分不同,用不同版本的编译器得分不同。。。(数组没有越界的情况下)
呜呜。。。至今没有ac。一直83分。。。抑郁了。。。
跪求神犇指明错误。。。
View Code
当然我不是说这题有多神,而是你数组开小了和开大了得分不同,用不同版本的编译器得分不同。。。(数组没有越界的情况下)
呜呜。。。至今没有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; }
相关文章推荐
- 【SPOJ】2798 Query on a tree again! QTREE系列之3 树链剖分
- spoj 2798 Query on a tree again! 树链剖分
- SPOJ 2798 Query on a tree again!
- SPOJ QTREE3 Query on a tree again! 树链剖分
- spoj Query on a tree again(树链剖分)
- spoj2798 QTREE3 Query on a tree again!
- 【SPOJ】2798 Query on a tree again!
- spoj375 Query on a tree(树链剖分 边权 入门题)
- SPOJ 375 Query on a tree(树链剖分)(QTREE)
- SPOJ QTREE- Query on a tree (树链剖分)
- SPOJ QTREE Query on a tree 树链剖分
- spoj 375 Query on a tree(树链剖分模版)
- SPOJ QTREE Query on a tree [树链剖分+线段树]
- spoj375 Query on a tree 树链剖分
- SPOJ 375 Query on a tree[树链剖分入门]
- spoj Query on a tree(树链剖分)
- SPOJ 375 QTREE Query on a tree 树链剖分水题
- 【spoj375】Query on a tree【树链剖分】【或者动态树,那样常数就完了T_T】
- SPOJ375——Query on a tree(树链剖分模板详解以及入门)
- 树链剖分 spoj 375 Query on a tree(剖分入门)