spoj Query on a tree again(树链剖分)
来源:互联网 发布:vr医疗软件 编辑:程序博客网 时间:2024/06/06 03:14
传送门
题解:链剖,然后线段树维护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;}
阅读全文
0 0
- spoj Query on a tree again(树链剖分)
- spoj QTREE3 Query on a tree again!
- SPOJ QTREE3 Query on a tree again! 树链剖分
- SPOJ Query on a tree (树链剖分)
- SPOJ---Query on a tree (树链剖分)
- spoj Query on a tree(树链剖分)
- 动态树LCT||树链剖分+线段树(SPOJ QTREE3 - Query on a tree again!)
- SPOJ-tree:Query on a tree (树链剖分)
- [SPOJ 375]Query On a Tree(树链剖分)
- SPOJ 375. Query on a tree【树链剖分】
- SPOJ 375. Query on a tree【树链剖分】
- SPOJ QTREE(Query on a tree树链剖分)
- spoj 375--Query On a Tree [树链剖分]
- spoj 375 Query on a tree 树链剖分
- spoj 375. Query on a tree(树链剖分)
- SPOJ QTREE Query on a tree --树链剖分
- [ SPOJ - QTREE]Query on a tree && 树链剖分
- SPOJ QTREE Query on a tree 树链剖分
- vector构造二维数组
- bzoj3357 [Usaco2004]等差数列
- 结合redis设计与实现的redis源码学习-4-dict(字典)
- 多线程:控制线程
- 五、jQuery中的事件本质
- spoj Query on a tree again(树链剖分)
- LeetCode题目: 25. Reverse Nodes in k-Group
- 数据库实例:mysql与mongo结合用户登录
- Ubuntu android studio 加载 arr
- CentOS上安装redis
- hdu 1811 Rank of Tetris (拓扑排序+并查集)
- UVA 156 【map的使用】【字符串模拟】
- 安装开发环境和开发软件和学习html5
- PB对Unicode的支持