RT,交了八遍。拍了几千组小数据没错,又拍了几组极限数据也没错,求好心的巨佬帮忙找找虫子QAQ。不胜感激awa
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define ll long long
#define fo(i,x,y) for(register int i=x;i<=y;++i)
#define go(i,x,y) for(register int i=x;i>=y;--i)
using namespace std;
inline int read(){int x=0,fh=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-') fh=-1; ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();} return x*fh;}
const int N=1e6+5;
struct Edge{
int to,next;
}e[N];
int head[N],tot,_tmp[N],st[N],ed[N],dfn,fa[N][20],dep[N],lg,blk,L=1,R,Ans,cnt[N],P[N],n,m;
int tmp[N],col[N],ans[N],od[N],bel[N];
void connect(int x,int y){
e[++tot]=(Edge){y,head[x]};
head[x]=tot;
}
struct Ask{
int u,v,l,r,num,fl;
void init(){
u=read(),v=read();
if(st[u]>st[v]) swap(u,v);
if(st[u]<=st[v]&&ed[v]<=ed[u]) fl=0,l=st[u],r=st[v];
else fl=1,l=ed[u],r=st[v];
}
bool operator<(const Ask &x)const{return bel[l]!=bel[x.l]?(bel[l]<bel[x.l]):(r<x.r);}
}a[N];
void dfs(int x,int fr){
dep[x]=dep[fr]+1;
fa[x][0]=fr;
st[x]=++dfn;col[dfn]=tmp[x];
for(int i=head[x];i;i=e[i].next){
int p=e[i].to;
if(p==fr) continue;
dfs(p,x);
}
ed[x]=++dfn;col[dfn]=tmp[x];
P[st[x]]=ed[x];
P[ed[x]]=st[x];
}
inline int lca(int x,int y){
if(dep[x]>dep[y]) swap(x,y);
go(i,lg,0) if(dep[fa[y][i]]>=dep[x]) y=fa[y][i];
if(x==y) return x;
go(i,lg,0) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
void del(int x){if(--cnt[x]==0) Ans--;}
void add(int x){if(cnt[x]++==0) Ans++;}
bool cmp(int x,int y){return _tmp[x]<_tmp[y];}
int main(){
cin>>n>>m;lg=log(n)/log(2);blk=sqrt(2*n);
fo(i,1,n) _tmp[i]=read(),od[i]=i;
sort(od+1,od+1+n,cmp);
int rp=0;
fo(i,1,n){
if(_tmp[od[i]]>_tmp[od[i-1]]) rp++;
tmp[od[i]]=rp;
}//fo(i,1,n) printf("%d ",tmp[i]);puts("");
fo(i,1,n<<1) bel[i]=(i-1)/blk;
fo(i,1,n-1){
int x=read(),y=read();
connect(x,y);
connect(y,x);
}
dfs(1,0);
fo(i,1,n)
fo(j,1,lg) fa[i][j]=fa[fa[i][j-1]][j-1];
fo(i,1,m) a[i].init(),a[i].num=i;
sort(a+1,a+1+m);
fo(i,1,m){
while(L<a[i].l){
if(P[L]<L||P[L]>R) del(col[L]);
else add(col[L]);
++L;
}
while(L>a[i].l){
--L;
if(P[L]<L||P[L]>R) add(col[L]);
else del(col[L]);
}
while(R<a[i].r){
++R;
if(P[R]<L||P[R]>R) add(col[R]);
else del(col[R]);
}
while(R>a[i].r){
if(P[R]<L||P[R]>R) del(col[R]);
else add(col[R]);
R--;
}
if(a[i].fl){
int k=lca(a[i].u,a[i].v);
add(tmp[k]);
ans[a[i].num]=Ans;
del(tmp[k]);
}else ans[a[i].num]=Ans;
}
fo(i,1,m) printf("%d\n",ans[i]);
return 0;
}