题意:
一棵树上每个结点都有一个值,q次询问,每次询问 U—>V 路径上有多少个不同的值
题解:
树分块+bitset能过,还挺快的。但是不开O2的话要算一下块的大小,大一点超内存,小一点超时
#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))
const int mod = 1e9+7;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 4e4+10;
struct edge{
int to,next;
}e[N<<1];
int head[N],cnt;
void add(int u,int v){
e[++cnt]={v,head[u]}; head[u]=cnt; swap(u,v);
e[++cnt]={v,head[u]}; head[u]=cnt;
}
int B=275,tot,last;
int a[N],lsh[N],lg[N];
int f[N][20],dep[N],nxt[146][146],id[N];
bitset<N>bt[146][146],tmp;
int dfs(int u,int fa){
f[u][0]=fa,dep[u]=dep[fa]+1;
for(int i=1;i<=lg[dep[u]];i++)f[u][i]=f[f[u][i-1]][i-1];
int madep=0;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v!=fa)madep=max(madep,dfs(v,u));
}
if(madep>=B)id[u]=++tot,madep=0;
return madep+1;
}
void dfs2(int x,int y){
if(id[x]){
nxt[id[x]][0]=x,nxt[id[x]][1]=y;
for(int i=x;i!=y;i=f[i][0])bt[id[x]][id[y]][a[i]]=1;
bt[id[x]][id[y]][a[y]]=1;
for(int i=2,z;i<=145;i++){
z=nxt[id[x]][i]=nxt[id[y]][i-1];
bt[id[x]][id[z]]|=bt[id[x]][id[y]];
bt[id[x]][id[z]]|=bt[id[y]][id[z]];
}
y=x;
}
for(int i=head[x];i;i=e[i].next){
int v=e[i].to;
if(v!=f[x][0])dfs2(v,y);
}
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y])x=f[x][lg[dep[x]-dep[y]]-1];
if(x==y)return x;
for(int i=lg[dep[x]]-1;i>=0;--i)if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
#define endl '\n'
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n,q; cin>>n>>q;
for(int i=1;i<=n;i++)cin>>a[i],lsh[i]=a[i];
sort(lsh+1,lsh+1+n); int m=unique(lsh+1,lsh+1+n)-lsh-1;
for(int i=1;i<=n;i++)a[i]=lower_bound(lsh+1,lsh+1+m,a[i])-lsh;
for(int i=1;i<n;i++){
lg[i]=lg[i-1]+(1<<lg[i-1]==i);
int u,v; cin>>u>>v;
add(u,v);
}
dfs(1,0); dfs2(1,0);
while(q--){
int x,y,p; cin>>x>>y;
x^=last; p=lca(x,y);
tmp.reset(); tmp[a[p]]=1;
for(;!id[x]&&x!=p;x=f[x][0]) tmp[a[x]]=1;
for(;!id[y]&&y!=p;y=f[y][0]) tmp[a[y]]=1;
if(id[x]){
for(int i=1;;i++)if(dep[nxt[id[x]][i]]<dep[p]){
tmp|=bt[id[x]][id[nxt[id[x]][i-1]]];
x=nxt[id[x]][i-1];
break;
}
}
if(id[y]){
for(int i=1;;i++)if(dep[nxt[id[y]][i]]<dep[p]){
tmp|=bt[id[y]][id[nxt[id[y]][i-1]]];
y=nxt[id[y]][i-1];
break;
}
}
for(;x!=p;x=f[x][0]) tmp[a[x]]=1;
for(;y!=p;y=f[y][0]) tmp[a[y]]=1;
cout<<(last=tmp.count())<<endl;
}
}