Description

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v),你需要回答u xor lastans和v这两个节点间有多少种不同的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。  

 

Input

第一行两个整数N,M。 第二行有N个整数,其中第i个整数表示点i的权值。 后面N-1行每行两个整数(x,y),表示点x到点y有一条边。 最后M行每行两个整数(u,v),表示一组询问。  

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 数据范围是N<=40000 M<=100000 点权在int范围内 

Output

  M行,表示每个询问的答案。  

Sample Input

8 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
3 8

Sample Output

4
4
      思路:    这题的原先版本是spoj上的题目,那个题目没有强制要求在线,可以使用树上莫队ac。     本题强制要求在线,所以我们要在树上采用分块方法,然后采用类似莫队的思想。           首先,把树分成n^(1/3) 块。    每个块定一个点作为中心,预处理两两中心之间的答案。然后每次询问找到那两个点的中心,像莫队那样暴力移动。显然每次最多移动n^(2/3)次。   所以复杂度m*n^(2/3)。 这样的时间复杂度理论上可以通过的,但是bzoj的服务器实在太弱了,于是被卡常了。。。   bzoj 2589 Count on a tree II 随笔 第1张
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 int const N = 40000 + 3;
  4 int const M = 100000 + 3;
  5 int const C = 40;
  6 struct edge {
  7     int to, nt;
  8 } e[N << 1];
  9 int tin[N], tout[N], h[N], cnt, sum, dep[N], f[N][16], a[N], b[N], n, m, st[N], top, sz, bl[N], num, cap[42];
 10 int c[42][42][N], kind[42][42], last;
 11 bool vis[42][42][N];
 12 template<class T>void read(T &x) {
 13     x = 0;
 14     char c = 0;
 15     while(!isdigit(c)) c = getchar();
 16     while(isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
 17 }
 18 void dfs(int x, int fa) {
 19     tin[x] = ++sum;
 20     f[x][0] = fa;
 21     dep[x] = dep[fa] + 1;
 22     for(int i = h[x]; i; i = e[i].nt) {
 23         int v = e[i].to;
 24         if(v == fa) continue;
 25         dfs(v, x);
 26     }
 27     tout[x] = ++sum;
 28 }
 29 
 30 void add(int a, int b) {
 31     e[++cnt].to = b;
 32     e[cnt].nt = h[a];
 33     h[a] = cnt;
 34 }
 35 void dfs2(int x, int fa) {
 36     int now = top;
 37     for(int i = h[x]; i; i = e[i].nt) {
 38         int v = e[i].to;
 39         if(v == fa) continue;
 40         dfs2(v, x);
 41         int tmp = top - now;
 42         if(tmp >= sz) {
 43             num++;
 44             while(tmp--) {
 45                 int t = st[top--];
 46                 cap[num] = x;
 47                 bl[t] = num;
 48             }
 49         }
 50     }
 51     st[++top] = x;
 52 }
 53 int ancestor(int x, int y) {
 54     return tin[x] <= tin[y] && tout[y] <= tout[x];
 55 }
 56 int lca(int x, int y) {
 57     if(ancestor(x, y)) return x;
 58     if(ancestor(y, x)) return y;
 59     for(int i = 15; i >= 0; i--)
 60         if(!ancestor(f[x][i], y))
 61             x = f[x][i];
 62     return f[x][0];
 63 }
 64 int update(int i, int j, int x) {
 65     if(vis[i][j][x]) {
 66         if(--c[i][j][a[x]] == 0) --kind[i][j];
 67     } else {
 68         if(++c[i][j][a[x]] == 1) ++kind[i][j];
 69     }
 70     vis[i][j][x] ^= 1;
 71 }
 72 int calc(int i, int j, int x, int y) {
 73     if(dep[x] < dep[y])
 74         swap(x, y);
 75     while(dep[x] > dep[y]) {
 76         update(i, j, x);
 77         x = f[x][0];
 78     }
 79     while(x ^ y) {
 80         update(i, j, x);
 81         update(i, j, y);
 82         x = f[x][0];
 83         y = f[y][0];
 84     }
 85 }
 86 int main() {
 87     scanf("%d%d", &n, &m);
 88     sz = max(1, n / C);
 89     for(int i = 1; i <= n; i++)
 90         read(a[i]), b[i] = a[i];
 91     sort(b + 1, b + n + 1);
 92     int k = unique(b + 1, b + n + 1) - b - 1;
 93     for(int i = 1; i <= n; i++)
 94         a[i] = lower_bound(b + 1, b + k + 1, a[i]) - b;
 95     for(int i = 1; i < n; i++) {
 96         int x, y;
 97         read(x);
 98         read(y);
 99         add(x, y);
100         add(y, x);
101     }
102     dfs(1, 1);
103     for(int j = 1; j <= 15; j++)
104         for(int i = 1; i <= n; i++)
105             f[i][j] = f[f[i][j - 1]][j - 1];
106     dfs2(1, 1);
107     if(top) {
108         ++num;
109         cap[num] = 1;
110         while(top) bl[st[top--]] = num;
111     }
112     for(int i = 1; i <= num; i++)
113         for(int j = i + 1; j <= num; j++) {
114             calc(i, j, cap[i], cap[j]);
115         }
116     while(m--) {
117         int x, y;
118         read(x);
119         read(y);
120         x ^= last;
121         int c = min(bl[x], bl[y]);
122         int d = max(bl[x], bl[y]);
123         calc(c, d, cap[bl[x]], x);
124         calc(c, d, cap[bl[y]], y);
125         update(c, d, lca(x, y));
126         printf("%d\n", last = kind[c][d]);
127         calc(c, d, cap[bl[x]], x);
128         calc(c, d, cap[bl[y]], y);
129         update(c, d, lca(x, y));
130     }
131     return 0;
132 }
View Code

 

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄