题目:
Description
You are given a tree with N nodes.The tree nodes are numbered from 1 to N.Each node has an integer weight.
We will ask you to perfrom the following operation:
- u v : ask for how many different integers that represent the weight of nodes there are on the path from u to v.
Input
In the first line there are two integers N and M.(N<=40000,M<=100000)
In the second line there are N integers.The ith integer denotes the weight of the ith node.
In the next N-1 lines,each line contains two integers u v,which describes an edge (u,v).
In the next M lines,each line contains two integers u v,which means an operation asking for how many different integers that represent the weight of nodes there are on the path from u to v.
Output
For each operation,print its result.
Example
Input:
2 5
7 8
Output: 4
4
网上大概看到两种解法,一种是:http://blog.youkuaiyun.com/kuribohg/article/details/41458639
用xor 思想求得
再一种就是这种直接求得:http://blog.youkuaiyun.com/u013598409/article/details/44943851
我说第二种:
先ORZ 这位博主的代码 :
2 #include <cstring>
3 #include <cstdlib>
4 #include <cmath>
5 #include <algorithm>
6 using namespace std;
7
8 const int N= 40001;
9 const int M= 161121;
10 const int K= 16;
11
12 struct R
13 {
14 int d,id;
15 }rk[N];
16 int n,m,w[N];
17 struct G
18 {
19 int v,nxt;
20 }map[N<< 1];
21 int tot,hd[N];
22 int in[N], out[N],lst[N<< 1],num;
23 int pre[K+ 2][N],dep[N];
24 struct Q
25 {
26 int l,r,anc,id;
27 }q[M];
28 int v[N],unit,res,l,r,has[N],ans[M]; // 注意ans的数据范围,为询问的个数
29
30 inline void ins( int u, int v)
31 {
32 map[++tot].v=v;
33 map[tot].nxt=hd[u];
34 hd[u]=tot;
35 }
36
37 void DFS( int now, int high)
38 {
39 dep[now]=high;
40 in[now]=++num;
41 lst[num]=now;
42
43 for ( int k=hd[now];k;k=map[k].nxt)
44 if (!dep[map[k].v])
45 {
46 DFS(map[k].v,high+ 1);
47 pre[ 0][map[k].v]=now;
48 }
49
50 out[now]=++num;
51 lst[num]=now;
52 }
53
54 inline int cmp1(R a,R b)
55 {
56 return a.d<b.d;
57 }
58
59 void init( void)
60 {
61 scanf( " %d%d ",&n,&m);
62 for ( int i= 1;i<=n;i++) scanf( " %d ",&w[i]);
63
64 int tmp,cnt;
65 for ( int i= 1;i<=n;i++) rk[i].d=w[i],rk[i].id=i;
66 sort(rk+ 1,rk+n+ 1,cmp1);
67 tmp=rk[ 1].d,w[rk[ 1].id]=cnt= 1;
68 for ( int i= 2;i<=n;i++)
69 {
70 if (tmp^rk[i].d) tmp=rk[i].d,cnt++;
71 w[rk[i].id]=cnt;
72 }
73
74 int x,y;
75 for ( int i= 1;i<n;i++)
76 {
77 scanf( " %d%d ",&x,&y);
78 ins(x,y),ins(y,x);
79 }
80
81 pre[ 0][ 1]= 1;
82 DFS( 1, 1);
83
84 for ( int i= 1;i<=K;i++)
85 for ( int j= 1;j<=n;j++)
86 pre[i][j]=pre[i- 1][pre[i- 1][j]];
87 }
88
89 inline int cmp(Q a,Q b)
90 {
91 return a.l/unit!=b.l/unit?a.l/unit<b.l/unit:a.r<b.r;
92 }
93
94 inline int min( int i, int j)
95 {
96 return i<j?i:j;
97 }
98
99 inline int max( int i, int j)
100 {
101 return i>j?i:j;
102 }
103
104 inline int LCA( int x, int y)
105 {
106 if (dep[x]>dep[y]) x^=y^=x^=y;
107 for ( int i=K;i+ 1;i--)
108 if (dep[y]-dep[x]>= 1<<i) y=pre[i][y];
109 if (x==y) return x; // 注意特判x=y时的LCA就是x=y
110 for ( int i=K;i+ 1;i--)
111 if (pre[i][x]^pre[i][y])
112 x=pre[i][x],y=pre[i][y];
113 return pre[ 0][x];
114 }
115
116 inline void solve( int i) // "有无"时的写法
117 {
118 if (has[lst[i]])
119 {
120 v[w[lst[i]]]--;
121 if (!v[w[lst[i]]]) res--;
122 has[lst[i]]= 0;
123 }
124 else
125 {
126 if (!v[w[lst[i]]]) res++;
127 v[w[lst[i]]]++;
128 has[lst[i]]= 1;
129 }
130 }
131
132 void work( void)
133 {
134 int x,y;
135 unit=( int)sqrt(num); // num instead of n
136 for ( int i= 1;i<=m;i++)
137 {
138 scanf( " %d%d ",&x,&y);
139 q[i].id=i;
140 if (x==y) q[i].anc=- 1;
141 else
142 {
143 q[i].anc=LCA(x,y);
144 if (q[i].anc!=x&&q[i].anc!=y)
145 {
146 q[i].l=min( out[x], out[y]);
147 q[i].r=max( in[x], in[y]);
148 }
149 else
150 {
151 q[i].l=min( in[x], in[y]);
152 q[i].r=max( in[x], in[y]);
153 } // (1)相同 (2)有1个为LCA:两个in (3) 都不同:max(in)&&min(out)
154 }
155 }
156 sort(q+ 1,q+m+ 1,cmp); // 注意用id弄到ans,不能直接输出
157
158 l= 1,r= 0;
159 for ( int i= 1;i<=m;i++)
160 if (q[i].anc==- 1) ans[q[i].id]= 1;
161 else
162 {
163 for (;l<q[i].l;l++) solve(l);
164 for (;q[i].l<l;l--) solve(l- 1);
165 for (;r<q[i].r;r++) solve(r+ 1);
166 for (;q[i].r<r;r--) solve(r);
167 if (lst[q[i].l]==q[i].anc||lst[q[i].r]==q[i].anc) // 注意加上lst
168 ans[q[i].id]=res;
169 else
170 {
171 solve( in[q[i].anc]);
172 ans[q[i].id]=res;
173 solve( in[q[i].anc]);
174 }
175 }
176
177 for ( int i= 1;i<=m;i++) printf( " %d\n ",ans[i]);
178 }
179
180 int main( void)
181 {
182 init();
183 work();
184
185 return 0;
186 }