題目鏈接,求鏈上顏色數。
Code:
#include<bits/stdc++.h>
#define maxn 40005
#define maxm 100005
#define S 300
using namespace std;
char cb[1<<20],*cs,*ct;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<20,stdin),cs==ct)?0:*cs++)
void read(int &a){
char c;while(!isdigit(c=getc()));
for(a=c-'0';isdigit(c=getc());a=a*10+c-'0');
}
int n,m,dep[maxn],fa[maxn],siz[maxn],son[maxn],top[maxn],A[maxn*2],st[maxn],ed[maxn],tim,bel[maxn*2];
int fir[maxn],nxt[maxn<<1],to[maxn<<1],tot;
void line(int x,int y){nxt[++tot]=fir[x],fir[x]=tot,to[tot]=y;}
void dfs1(int u,int ff){
dep[u]=dep[fa[u]=ff]+1,siz[u]=1;
for(int i=fir[u],v;i;i=nxt[i]) if((v=to[i])!=ff)
dfs1(v,u),siz[u]+=siz[v],siz[v]>siz[son[u]]&&(son[u]=v);
}
void dfs2(int u,int tp){
top[u]=tp,A[st[u]=++tim]=u;
if(son[u]) dfs2(son[u],tp);
for(int i=fir[u],v;i;i=nxt[i]) if(!top[v=to[i]]) dfs2(v,v);
A[ed[u]=++tim]=u;
}
int LCA(int u,int v){
for(;top[u]!=top[v];u=fa[top[u]]) if(dep[top[u]]<dep[top[v]]) swap(u,v);
return dep[u]<dep[v]?u:v;
}
struct node{
int l,r,lca,id;
bool operator < (const node &p)const{return bel[l]==bel[p.l]?(bel[l]&1?r>p.r:r<p.r):bel[l]<bel[p.l];}
}q[maxm];
int ans[maxm],cnt[maxn],num,a[maxn],b[maxn];
bool use[maxn];
void mdf(int x){
if(use[x]) {if(!--cnt[a[x]]) --num;}
else {if(!cnt[a[x]]++) ++num;}
use[x]^=1;
}
int main()
{
int x,y;
read(n),read(m);
for(int i=1;i<=n;i++) read(a[i]),b[i]=a[i];
sort(b+1,b+1+n); int len=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+len,a[i])-b;
for(int i=1;i<n;i++) read(x),read(y),line(x,y),line(y,x);
dfs1(1,0),dfs2(1,1);
for(int i=1;i<=tim;i++) bel[i]=(i-1)/S;
for(int i=1,z;i<=m;i++){
read(x),read(y); if(st[x]>st[y]) swap(x,y);
if((z=LCA(x,y))==x) q[i]=(node){st[x],st[y],0,i};
else q[i]=(node){ed[x],st[y],z,i};
}
sort(q+1,q+1+m);
x=1,y=0;
for(int i=1;i<=m;i++){
while(x>q[i].l) mdf(A[--x]);
while(y<q[i].r) mdf(A[++y]);
while(x<q[i].l) mdf(A[x++]);
while(y>q[i].r) mdf(A[y--]);
ans[q[i].id]=num+(q[i].lca&&!cnt[a[q[i].lca]]);
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
}