#include<bits/stdc++.h>
#pragma GCC optimize(3)
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
using namespace std;
#define in inline
#define ll int
const ll N=114514,M=1919810,inf=2147483646;
ll n,m,w[N],cnt[N],bel[N],ns,nq,v[N];
ll dfn[2*N],tot,fir[N],las[N],dept[N],f[N][24],lg[N],vis[N];
struct query{
int l,r,id,lca;
}q[N];
in bool cmp(query x,query y){
return bel[x.l]^bel[y.l]?bel[x.l]<bel[y.l]:((bel[x.l]&1)?x.r<y.r:x.r>y.r);
}
struct xx{
int next,to;
}e[2*N];
int head[2*N],e_cnt;
in void add(ll x,ll y){
e[++e_cnt].next=head[x];
e[e_cnt].to=y;
head[x]=e_cnt;
}
in void dfs_euler(int u,int fa){
dfn[++tot]=u;
fir[u]=tot;
for(int i=head[u];i;i=e[i].next){
ll v=e[i].to;
if(v==fa) continue;
dept[v]=dept[u]+1;
f[v][0]=u;
for(int j=1;j<=lg[dept[v]];++j)
f[v][j]=f[f[v][j-1]][j-1];
dfs_euler(v,u);
}
dfn[++tot]=u;
las[u]=tot;
}
in int query_lca(ll a,ll b){
if(dept[a]<dept[b]) swap(a,b);
if(a==b) return a;
for(int i=lg[dept[a]];i>=0;--i)
if(dept[f[a][i]]>=dept[b])
a=f[a][i];
if(a==b) return a;
for(int i=lg[dept[a]];i>=0;--i)
if(f[a][i]!=f[b][i]){
a=f[a][i];
b=f[b][i];
}
return f[a][0];
}
ll now,ans[N];
in void add(ll x){
now+=(++cnt[w[x]]==1);
}
in void del(ll x){
now-=(cnt[w[x]]--==1); //写错了
}
in void change(int x){
vis[x]?del(x):add(x);
vis[x]^=1;
}
in void init(){
ns=2*n/sqrt(m*2.0/3),nq=n/ns+(n%ns!=0);
for(int i=1;i<=nq;++i)
for(int j=ns*(i-1)+1;j<=ns*i;++j)
bel[j]=i;
for(int i=2;i<=n;++i) lg[i]=lg[i>>1]+1;
dept[1]=1;
}
in ll read(){
ll x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
in void write(ll x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
return;
}
in void SWAP(ll a,ll b){
ll c=a;
a=b,b=c;
}
int main(){
n=read(); m=read();
init();
for(int i=1;i<=n;++i) w[i]=read(),v[i]=w[i];
sort(v+1,v+n+1);
ll nm=unique(v+1,v+n+1)-v;
for(int i=1;i<=n;++i)
w[i]=lower_bound(v+1,v+nm+1,w[i])-v;
for(int i=1;i<n;++i){
ll a,b;
a=read(); b=read();
add(a,b),add(b,a);
}
dfs_euler(1,0);
for(int i=1;i<=m;++i){
ll a,b,lca;
a=read(),b=read(),lca=query_lca(a,b);
q[i].id=i;
if(fir[a]>fir[b]) swap(a,b);
if(a==lca) q[i].l=fir[a],q[i].r=fir[b];
else q[i].l=las[a],q[i].r=fir[b],q[i].lca=lca;
}
sort(q+1,q+m+1,cmp);
ll l=1,r=0;
for(int i=1;i<=m;++i){
while(l<q[i].l) change(dfn[l++]);
while(l>q[i].l) change(dfn[--l]);
while(r<q[i].r) change(dfn[++r]);
while(r>q[i].r) change(dfn[r--]);
if(q[i].lca) change(q[i].lca);
ans[q[i].id]=now;
if(q[i].lca) change(q[i].lca);
}
for(int i=1;i<=m;++i) write(ans[q[i].id]),printf("\n");
return 0;
}
/*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
7 8*/
是的你没看错,火车头都搬上去了,还是TLE,我都怀疑是哪个地方写错了。