spoj 2798 Query on a tree again! 树链剖分

题意:给定一棵树,每个节点颜色是黑色或者是白色。初始时,全白。

定义两种操作

0 i 改变第i个节点

1 v 询问从1到v的路径上,第一个黑节点

  1 #include<iostream>
2 #include<cstring>
3 #include<cmath>
4 #include<cstdio>
5 using namespace std;
6 #define MAXN 100010
7 #define INF 987654321
8 struct node
9 {
10 int r;
11 node *next;
12 };
13 struct tree_node
14 {
15 int left,right;
16 int num;
17 };
18 node *graph[MAXN];
19 node memo[MAXN*2];
20 tree_node tree[4*MAXN];
21 int d[MAXN],father[MAXN],line[MAXN],son[MAXN],top[MAXN],mark[MAXN],home[MAXN];
22 int n,m,label,color[MAXN],etop;
23 void add(int x,int y)
24 {
25 node *p=&memo[etop++];
26 p->r=y; p->next=graph[x]; graph[x]=p;
27 p=&memo[etop++];
28 p->r=x; p->next=graph[y]; graph[y]=p;
29 }
30 int dfs1(int i,int deep,int fa)
31 {
32 d[i]=deep; father[i]=fa;
33 int size=1,maxsize=0,temp;
34 for(node *p=graph[i];p;p=p->next)
35 if(p->r!=father[i])
36 {
37 temp=dfs1(p->r,deep+1,i);
38 if(temp>maxsize)
39 {
40 maxsize=temp; son[i]=p->r;
41 }
42 size+=temp;
43 }
44 return size;
45 }
46 void dfs2(int x,int y)
47 {
48 mark[x]=++label; top[x]=y;
49 home[label]=x;
50 if(son[x]==-1) return ;
51 dfs2(son[x],y);
52 for(node *p=graph[x];p;p=p->next)
53 if(p->r!=father[x]&&p->r!=son[x]) dfs2(p->r,p->r);
54 }
55 void build_tree(int i)
56 {
57 tree[i].num=INF;
58 if(tree[i].left==tree[i].right) return ;
59 int mid=(tree[i].left+tree[i].right)/2;
60 tree[2*i].left=tree[i].left; tree[2*i].right=mid;
61 tree[2*i+1].left=mid+1; tree[2*i+1].right=tree[i].right;
62 build_tree(2*i); build_tree(2*i+1);
63 }
64 void change(int i,int x)
65 {
66 if(tree[i].left==tree[i].right)
67 {
68 if(tree[i].num==INF) tree[i].num=tree[i].left;
69 else tree[i].num=INF;
70 return ;
71 }
72 int mid=(tree[i].left+tree[i].right)/2;
73 if(x<=mid) change(2*i,x);
74 else change(2*i+1,x);
75 tree[i].num=min(tree[2*i].num,tree[2*i+1].num);
76 }
77 int search(int i,int x,int y)
78 {
79 if(tree[i].left==x&&tree[i].right==y)
80 return tree[i].num;
81 int mid=(tree[i].left+tree[i].right)/2;
82 if(y<=mid) return search(2*i,x,y);
83 else if(x>mid) return search(2*i+1,x,y);
84 else return min(search(2*i,x,mid),search(2*i+1,mid+1,y));
85 }
86 void build()
87 {
88 dfs1(1,1,-1);
89 dfs2(1,1);
90 tree[1].left=1; tree[1].right=n;
91 build_tree(1);
92 }
93
94
95 void solve()
96 {
97 int c,x,nx,ans;
98 for(int i=1;i<=m;i++)
99 {
100 scanf("%d%d",&c,&x);
101 if(c==0) change(1,mark[x]);
102 else
103 {
104 for(ans=INF;x!=-1;x=father[nx])
105 {
106 nx=top[x];
107 ans=min(ans,search(1,mark[nx],mark[x]));
108 }
109 if(ans==INF) printf("-1\n");
110 else printf("%d\n",home[ans]);
111 }
112 }
113 }
114 int main()
115 {
116 scanf("%d%d",&n,&m);
117 int x,y;
118 int i;
119 memset(graph,0,sizeof(graph));
120 memset(son,0xff,sizeof(son));
121 etop=label=0;
122 for(i=1;i<n;i++)
123 {
124 scanf("%d%d",&x,&y);
125 add(x,y);
126 }
127 build();
128 solve();
129 return 0;
130 }



原文地址:https://www.cnblogs.com/myoi/p/2379518.html