BSOJ3194:黑白树 树链剖分 TLE90分
来源:互联网 发布:数值模拟软件 编辑:程序博客网 时间:2024/04/30 05:31
这个应该能交过SPOJ上的题,没试过
3194 -- 【Astar 2008】黑白树
Description
在图论中,包含n个结点(结点编号为1~n)、n-1条边的无向连通图被称为树。在树中,任意一对结点间的简单路径总是惟一的。你拥有一棵白色的树——所有节点都是白色的。接下来,你需要处理c条指令:
修改指令(0 v):改变一个给定结点的颜色(白变黑,黑变白)
查询指令(1 v):询问从结点1到一个给定结点所经过的第一个黑色结点编号(假设沿着简单路径走)。
注意,在查询指令中,必须从结点1而不是结点v出发。如果结点1本身就是黑色,查询指令应该返回1。
Input
第一行包含两个正整数n,c,即结点数和指令条数。
以下n-1行,每行两个正整数(ui,vi)(1≤ui<vi≤n),表示结点ui到vi之间有一条无向边.
以下c行,每行两个整数(c,v)。当c=0时表示修改指令,其中v代表被修改的结点编号;c=1时表示查询指令。
你的程序需要输出结点1到结点v之间路径的第一个黑色结点编号。
在第一条指令执行前,所有结点都是白色的。
Output
对于每个查询操作(c=1的操作),输出一行,包含一个整数,即第一个黑色结点的编号。如果不存在黑色结点,输出-1。
Sample Input
9 8
1 2
1 3
2 4
2 9
5 9
7 9
8 9
6 8
1 3
0 8
1 6
1 7
0 2
1 9
0 2
1 9
Sample Output
-1
8
-1
2
-1
Hint
【数据范围】
0≤N≤1000000,0≤C≤1000000
草稿如下。
直接插入tid值
inline优化+getint优化+哲学swap,仍然在第二组随机100W数据下超时
草稿如下。
直接插入tid值
#include<iostream>#include<cstdio>#include<cstring>#define L(x) (x<<1)#define R(x) (x<<1|1)#define INF 0x7fffffffusing namespace std;int fa[3000005]={0},top[3000005]={0},son[3000005]={0},size[3000005]={0};int tid[3000005]={0},dep[3000005]={0};int rank[3000005]={0};struct SegmentTree{int l,r,p;}tree[3000005];int n,m;inline void swap(int &a,int &b){a^=b;b^=a;a^=b;}inline int getint(){int bj=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')bj=-1;ch=getchar();}int ret=0;while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();return ret*bj;}struct Edge{int to,next;}w[3000005]={0};int tim=0;int minn=INF;int cnt=0;int h[3000005]={0};inline void add(int x,int y){cnt++;w[cnt].to=y;w[cnt].next=h[x];h[x]=cnt;}void DFS1(int x,int f,int d){dep[x]=d;fa[x]=f;size[x]=1;for(int i=h[x];i;i=w[i].next){int to=w[i].to;if(to!=f){DFS1(to,x,d+1);size[x]+=size[to];if(son[x]==0||size[son[x]]<size[to])son[x]=to;}}}void DFS2(int x,int tp){top[x]=tp;tid[x]=++tim;rank[tim]=x;if(son[x]==0)return;DFS2(son[x],tp);for(int i=h[x];i;i=w[i].next){int to=w[i].to;if(to!=son[x]&&to!=fa[x])DFS2(to,to);}}inline void Pushup(int x){ tree[x].p=min(tree[L(x)].p,tree[R(x)].p); return;}void build(int l,int r,int root){tree[root].l=l;tree[root].r=r; tree[root].p=INF;if(l==r)return;int mid=(l+r)>>1;build(l,mid,L(root));build(mid+1,r,R(root));Pushup(root);//}inline void change(int x,int root){if(tree[root].l==tree[root].r)//{if(tree[root].p==INF)tree[root].p=tree[root].l;else tree[root].p=INF;return;}int mid=(tree[root].l+tree[root].r)>>1;if(x<=mid)change(x,L(root));else change(x,R(root));Pushup(root);}inline void get(int l,int r,int root)//{if(l<=tree[root].l&&tree[root].r<=r){minn=min(minn,tree[root].p);return;}int mid=(tree[root].l+tree[root].r)>>1;if(l<=mid)get(l,r,L(root));if(r>mid) get(l,r,R(root));}inline void mi(int x,int y){int t1=top[x],t2=top[y];while(t1!=t2){if(dep[t1]<dep[t2]){swap(t1,t2);swap(x,y);}get(tid[t1],tid[x],1);x=fa[t1];t1=top[x];}if(dep[x]>dep[y])swap(x,y);get(tid[x],tid[y],1);if(minn==INF)printf("-1\n");else printf("%d\n",rank[minn]);}int main(){ n=getint();m=getint(); for(int i=1;i<n;i++) { int a,b; a=getint();b=getint(); add(a,b); add(b,a);}DFS1(1,0,1);DFS2(1,1);build(1,n,1);while(m--){int cmd,a;cmd=getint();a=getint();if(cmd==0)change(tid[a],1);else {minn=INF;mi(1,a);}}return 0;}
0 0
- BSOJ3194:黑白树 树链剖分 TLE90分
- 黑白树
- 进程管理-----黑白棋子之分
- bzoj 3319: 黑白树
- [XJOI]黑白树
- BZOJ 3319 黑白树
- bzoj 3319 黑白树
- 3319: 黑白树
- CodeM 黑白树
- [COGS2278]树黑白
- 【UER #4】被删除的黑白树
- 【bzoj3319】【黑白树】【并查集】
- 美团codeM预赛B 黑白树
- 从黑白到黑白
- BZOJ 3319 黑白树 并查集+线段树
- COGS-2278 树黑白(动态树分治)
- bzoj 3319: 黑白树 (并查集)
- CodeM美团B轮A题 黑白树 【贪心】
- BSOJ1120:树上的询问 树链剖分 区间修改 单点查询
- Android的各种布局
- webmin的安装
- hdu(1686)——Oulipo
- BSOJ1125:树Tree 树链剖分 单点修改 区间取反 区间查询
- BSOJ3194:黑白树 树链剖分 TLE90分
- 记一次手贱之旅--Ubuntu安装NVIDIA驱动
- LeetCode 136.137. 260.Single Number ⅠII III
- BSOJ2381:捉迷藏 括号序列 线段树维护
- 【点分治】poj1741
- Android基础:startActivityForResult+onActivityResult+setResult
- 【点分治】poj1741
- 阿里2015实习生招聘前端方向--编程题(2)
- BSOJ2764:树中点对统计 点分治