题目:
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:8 58 2 105 2 9 3 8 5 7 7 1 2 1 3 1 4 3 5 3 6 3 7 4 8
2 5
7 8
Output: 4
4
网上大概看到两种解法,一种是:http://blog.csdn.net/kuribohg/article/details/41458639
用xor 思想求得
再一种就是这种直接求得:http://blog.csdn.net/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 ",ans[i]);
178 }
179
180 int main(void)
181 {
182 init();
183 work();
184
185 return 0;
186 }