spoj Query on a tree again(树链剖分)
2017-09-28 22:52
316 查看
传送门
题解:链剖,然后线段树维护1/0,每一次贪心地往左区间寻找(一条链对应到DFS序上越左深度越浅),最后返回一个下标。复杂度O(n*logn^2)
另外一种线段树写法戳这儿
P.S.用SPOJ评测一定不建议在main函数外写注释。
![](http://img.blog.csdn.net/20170928225058097?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvS0dWMDkz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
题解:链剖,然后线段树维护1/0,每一次贪心地往左区间寻找(一条链对应到DFS序上越左深度越浅),最后返回一个下标。复杂度O(n*logn^2)
另外一种线段树写法戳这儿
P.S.用SPOJ评测一定不建议在main函数外写注释。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int MAXN=100004; int n,m; int head[MAXN],edge=0; int siz[MAXN],son[MAXN],fa[MAXN],top[MAXN],tid[MAXN],rk[MAXN],dep[MAXN],tim=0; struct EDGE { int v,nxt; }e[MAXN<<1]; inline int read() { int x=0;char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); return x; } inline void adde(int u,int v) { e[++edge].nxt=head[u],e[edge].v=v,head[u]=edge; e[++edge].nxt=head[v],e[edge].v=u,head[v]=edge; } /*------------DCP------------*/ void dfs1(int p,int father,int d) { siz[p]=1,fa[p]=father,dep[p]=d; for (int i=head[p];~i;i=e[i].nxt) { int v=e[i].v; if (v^father) { dfs1(v,p,d+1); siz[p]+=siz[v]; if (son[p]==-1||siz[son[p]]<siz[v]) son[p]=v; } } } void dfs2(int p,int tp) { top[p]=tp,tid[p]=++tim,rk[tim]=p; if (son[p]==-1) return ; dfs2(son[p],tp); for (int i=head[p];~i;i=e[i].nxt) { int v=e[i].v; if (v^fa[p]&&v^son[p]) dfs2(v,v); } } /*------------SegTree------------*/ int sum[MAXN<<2]; inline void pushup(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void modify(int rt,int l,int r,int pos,int val) { if (l==r) {sum[rt]^=val;return ;} int mid=(l+r)>>1; if (pos<=mid) modify(rt<<1,l,mid,pos,val); else modify(rt<<1|1,mid+1,r,pos,val); pushup(rt); } int query(int rt,int l,int r,int L,int R) { if (!sum[rt]) return 0; if (l==r) return l; int mid=(l+r)>>1; int ans=0; if (L<=mid) ans=query(rt<<1,l,mid,L,R); if (ans) return ans; if (mid<R) ans=query(rt<<1|1,mid+1,r,L,R); return ans; } int ask(int x,int y) { int ans=0; while (top[x]^top[y]) { if (dep[top[x]]<dep[top[y]]) x^=y^=x^=y; int temp=query(1,1,n,tid[top[x]],tid[x]); if (temp) ans=temp; x=fa[top[x]]; } if (dep[x]>dep[y]) x^=y^=x^=y; int temp=query(1,1,n,tid[x],tid[y]); if (temp) ans=temp; return ans; } int main() { // freopen("spoj qota.in","r",stdin); memset(head,-1,sizeof(head)); memset(son,-1,sizeof(son)); n=read(),m=read(); for (register int i=1;i<n;++i) { int u=read(),v=read(); adde(u,v); } dfs1(1,0,0); dfs2(1,1); for (register int C_Ronaldo=0;C_Ronaldo<m;++C_Ronaldo) { int x=read(),y=read(); if (!x) modify(1,1,n,tid[y],1); else { int ret=ask(1,y); printf("%d\n",ret?rk[ret]:-1); } } return 0; }
相关文章推荐
- spoj 2798 Query on a tree again! 树链剖分
- SPOJ QTREE3 Query on a tree again! 树链剖分
- 【SPOJ】2798 Query on a tree again! QTREE系列之3 树链剖分
- SPOJ 2798 Query on a tree again 树链剖分
- SPOJ Query on a tree 树链剖分 水题
- SPOJ---Query on a tree (树链剖分)
- spoj 375 Query on a tree(树链剖分模版)
- 【树链剖分模板】【SPOJ 375】 Query on a tree
- 【SPOJ Query on a tree 】 (树链剖分)
- SPOJ - QTREE Query on a tree(树链剖分)
- SPOJ 375 Query on a tree(树链剖分)
- spoj 375 Query on a tree (树链剖分)
- SPOJ QTREE3 - Query on a tree again!
- SPOJ 375 Query on a tree(树链剖分)
- spoj 375 Query on a tree(树链剖分)
- 【spoj375】Query on a tree【树链剖分】【或者动态树,那样常数就完了T_T】
- 【SPOJ】2798 Query on a tree again!
- SPOJ QTREE - Query on a tree 【树链剖分模板】
- SPOJ QTREE Query on a tree [树链剖分+线段树]
- SPOJ-375 QTREE - Query on a tree (树链剖分 边权转点权)