博客已经好久不更新了。
一来是身体差,二来也是没有人看。
再者说自己也比较懒
然后兴致勃勃跑去直接写了个二维bit……
后来觉得不过瘾就去写了个树上莫队QAQ
然后……
因为自己纸张调了一下午。
TAT
其实还是很好懂的,随便找找就能找到资料。
#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define v edge[i].to
#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)
using namespace std;
const int N = 100001;
struct Edge{int next,to;}edge[N << 1];
int B,n,m,rt,cnt,head[N],tim,dfn[N],sz[N],ans,bel[N],dep[N],Ans[N],fa[N],son[N],top[N],stk[N],tot,Top,cur[N];
int col[N];
bool vis[N];
struct Query{int x,y,id;}q[N];
bool cmp(Query a,Query b){return bel[a.x] == bel[b.x] ? dfn[a.y] < dfn[b.y] : bel[a.x] < bel[b.x];}
void save(int a,int b){edge[cnt] = (Edge){head[a],b},head[a] = cnt ++;}
int dfs(int x)
{
int siz = 0;
sz[x] = 1;dfn[x] = ++ tim;
RepG(i,x)
if(v != fa[x])
{
fa[v] = x;
dep[v] = dep[x] + 1;
siz += dfs(v);
sz[x] += sz[v];
if(sz[son[x]] < sz[v])
son[x] = v;
if(siz >= B)
{
tot ++;
for(int j = 1;j <= siz;++ j)bel[stk[Top --]] = tot;
siz = 0;
}
}
stk[++ Top] = x;
return siz + 1;
}
void dfs(int x,int tp)
{
top[x] = tp;
if(!son[x])return;
dfs(son[x],tp);
RepG(i,x)if(v != fa[x] && v != son[x])dfs(v,v);
}
int LCA(int x,int y)
{
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]])swap(x,y);
x = fa[top[x]];
}
return dep[x] < dep[y] ? x : y;
}
void Rev(int x)
{
vis[x] ^= 1;
if(vis[x])cur[col[x]] ++,ans += (cur[col[x]] == 1);
else cur[col[x]] --,ans -= (!cur[col[x]]);
}
void Move(int x,int y)
{
int z = LCA(x,y);
while(x != z)Rev(x),x = fa[x];
while(y != z)Rev(y),y = fa[y];
}
int b[N];
int Bin(int x)
{
int l = 1,r = n,mid;
while(l < r)
{
mid = l + r >> 1;
if(b[mid] < x)l = mid + 1;
else r = mid;
}
return l;
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("out","w",stdout);
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
B = (int)sqrt(n);
Rep(i,n)scanf("%d",&col[i]),b[i] = col[i];
sort(b + 1,b + 1 + n);
Rep(i,n)col[i] = Bin(col[i]);
for(int i = 1,x,y;i < n;++ i)
{
scanf("%d%d",&x,&y);
save(x,y),save(y,x);
}
rt = 1;
int re = dfs(rt);dfs(rt,rt);
Rep(i,re)bel[stk[Top --]] = tot;
Rep(i,m)
{
scanf("%d%d",&q[i].x,&q[i].y),q[i].id = i;
if(bel[q[i].x] > bel[q[i].y])swap(q[i].x,q[i].y);
}
sort(q + 1,q + 1 + m,cmp);
int lca,x,y;
x = y = 1;
for(int i = 1;i <= m;++ i)
{
Move(q[i].x,x);
Move(q[i].y,y);
x = q[i].x,y = q[i].y;
lca = LCA(x,y);
Rev(lca);
Ans[q[i].id] = ans;
Rev(lca);
}
Rep(i,m)printf("%d\n",Ans[i]);
return 0;
}