显示 0.00s,难道 map真的这么慢吗???
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int M = 2e5 + 10;
int n, m, blk, col[N], dep[N], f[N][17];
int clk, in[N], out[N], euler[N << 1];
int id, head[N << 1], nxt[N << 1], to[N << 1];
int tot, ans[M];
map<int, int> tcol;
bool vis[N];
struct event{
int s, t, idx;
bool operator < (const event &p) const {
if(s / blk != p.s / blk) return s < p.s;
return t < p.t;
}
} q[M];
void add(int u, int v){
to[++id] = v;
nxt[id] = head[u], head[u] = id;
}
void dfs(int u, int fa){
f[u][0] = fa;
in[u] = ++clk, euler[clk] = u;
for(int i=1;i<=16;i++)
f[u][i] = f[f[u][i - 1]][i - 1];
for(int i=head[u];i;i=nxt[i]){
int v = to[i];
if(v == fa)
continue;
dep[v] = dep[u] + 1;
dfs(v, u);
}
out[u] = ++clk, euler[clk] = u;
}
int lca(int u, int v){
if(dep[u] < dep[v])
swap(u, v);
for(int i=16;i>=0;i--)
if(dep[f[u][i]] >= dep[v])
u = f[u][i];
if(u == v)
return u;
for(int i=16;i>=0;i--)
if(f[u][i] != f[v][i])
u = f[u][i], v = f[v][i];
return f[u][0];
}
void calc(int k){
if(vis[k]){
--tcol[col[k]];
if(tcol[col[k]] == 0)
--tot;
}
else{
++tcol[col[k]];
if(tcol[col[k]] == 1)
++tot;
}
vis[k] ^= 1;
}
int main(){
scanf("%d%d", &n, &m);
for(int i=1;i<=n;i++)
scanf("%d", &col[i]);
for(int i=1,u,v;i<n;i++){
scanf("%d%d", &u, &v);
add(u, v), add(v, u);
}
dfs(1, 0);
// for(int i=1;i<=clk;i++)
// cout << euler[i];
blk = sqrt(clk);
for(int i=1,u,v;i<=m;i++){
scanf("%d%d", &u, &v);
if(dep[u] > dep[v])
swap(u, v);
if(lca(u, v) == u)
q[i] = (event){in[u], in[v], i};
else
q[i] = (event){out[u], in[v], i};
}
sort(q + 1, q + 1 + m);
// for(int i=1;i<=m;i++)
// cout << q[i].s << ' ' << q[i].t << endl;
int l = 1, r = 0;
for(int i=1;i<=m;i++){
while(r < q[i].t)
calc(euler[++r]);
while(l > q[i].s)
calc(euler[--l]);
while(r > q[i].t)
calc(euler[r--]);
while(l < q[i].s)
calc(euler[l++]);
int chl = lca(euler[q[i].s], euler[q[i].t]);
ans[q[i].idx] = tot + (tcol[col[chl]] == 0);
}
for(int i=1;i<=m;i++)
printf("%d\n", ans[i]);
return 0;
}