树上莫队
利用欧拉序序列来确定询问L,R
具体地,当查询u,v。
若lca(u,v)u||lca(u,v)v,[min(in[u],in[v]),max(in[u],in[v])]
否则 [out[u],in[v]] (满足out[u]<in[v])
模板题[https://ac.nowcoder.com/acm/contest/20376/A]
int col[maxn];
vector<int>e[maxn];
struct node{
int l,r;
int id;
int flag;
int Lca;
};
int idx[maxn];
int cnt=1;
vector<int>V;
int dep[maxn];
int f[maxn];
int anc[maxn][27];
bool cmp(const node&a,const node&b){
if(idx[a.l]!=idx[b.l])return idx[a.l]<idx[b.l];
if(idx[a.l]&1){
return idx[a.r]<idx[b.r];
}else return idx[a.r]>idx[b.r];
}
void per_dfs(int u,int fa){
f[u]=fa;
anc[u][0]=fa;
dep[u]=dep[fa]+1;
V.pb(u);
for(int v:e[u]){
if(v==fa)continue;
per_dfs(v,u);
}
V.pb(u);
}
int lca(int u,int v){
if(dep[v]>dep[u])swap(u,v);
for(int j=26;j>=0;j--){
if(dep[anc[u][j]]>=dep[v]){
u=anc[u][j];
}
if(u==v)return u;
}
for(int j=26;j>=0;j--){
if(anc[u][j]!=anc[v][j]){
u=anc[u][j];
v=anc[v][j];
}
}
return anc[u][0];
}
int vis[maxn];
int tot[maxn];
int ans[maxn];
int in[maxn];
int out[maxn];
node qr[maxn];
int sum=0;
void modify(int p){
if(vis[p]){
tot[col[p]]--;
if(tot[col[p]]==0)sum--;
}else{
tot[col[p]]++;
if(tot[col[p]]==1)sum++;
}
vis[p]^=1;
}
void solve(){
int n;cin>>n;
rep(i,1,n)cin>>col[i];
dep[0]=-1;
V.pb(0);
int bs= (int)pow(2*n,2.0/3.0);
rep(i,1,2*n){
if(i>cnt*bs)cnt++;idx[i]=cnt;
}
rep(i,1,n-1){
int u,v;cin>>u>>v;
e[u].pb(v);e[v].pb(u);
}
per_dfs(1,0);
for(int j=1;j<=26;j++){
for(int i=1;i<=n;i++){
anc[i][j]=anc[anc[i][j-1]][j-1];
}
}
for(int i=1;i<=2*n;i++){
if(!in[V[i]])in[V[i]]=i;
else out[V[i]]=i;
}
int q;cin>>q;
rep(i,1,q){
int u,v;cin>>u>>v;
int L=0,R=0,flag=0;
if(lca(u,v)==u||lca(u,v)==v){
L=min(in[u],in[v]);
R=max(in[u],in[v]);
}else{
if(out[u]<in[v]){
L=out[u];R=in[v];
}else L=out[v],R=in[u];
flag=1;
}
qr[i].id=i;qr[i].l=L;qr[i].r=R;qr[i].flag=flag;qr[i].Lca=lca(u,v);
}
sort(qr+1,qr+1+q,cmp);
int L=1,R=0;
rep(i,1,q){
int _l=qr[i].l,_r=qr[i].r;
while(L<_l)modify(V[L++]);
while(L>_l)modify(V[--L]);
while(R<_r)modify(V[++R]);
while(R>_r)modify(V[R--]);
if(qr[i].flag){
modify(qr[i].Lca);
ans[qr[i].id]=sum;
modify(qr[i].Lca);
}else ans[qr[i].id]=sum;
}
for(int i=1;i<=q;i++)cout<<ans[i]<<endl;
}

浙公网安备 33010602011771号