捞(求助树上莫队)
查看原帖
捞(求助树上莫队)
692647
tanghg楼主2024/1/21 13:52

求助帮忙,悬赏一关。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=3e5+5;
struct query{
    ll l,r,time,lca;
    ll kl,kr;
    bool operator<(const query&K)const{
        if(kl!=K.kl){
            return kl<K.kl;
        }
        return kr<K.kr;
    }
}q[MAXN];
vector<ll>adj[MAXN*2];
ll s[MAXN],e[MAXN];
ll p[MAXN*2],sz;
ll dep[MAXN],fa[MAXN][31];
void dfs(ll u,ll f){
    dep[u]=dep[f]+1;
    fa[u][0]=f;
    for(int i=1;i<30;++i){
        fa[u][i]=fa[fa[u][i-1]][i-1];
    }
    p[++sz]=u;
    s[u]=sz;
    for(auto i:adj[u]){
        if(i==f){
            continue;
        }
        dfs(i,u);
    }
    p[++sz]=u;
    e[u]=sz;
}
ll lca(ll u,ll v){
    if(dep[u]>dep[v]){
        swap(u,v);
    }
    ll val=dep[v]-dep[u];
    for(int i=0;val;++i){
        if(val&1){
            v=fa[v][i];
        }
        val>>=1;
    }
    if(u==v){
        return u;
    }
    for(int i=29;i>=0;--i){
        if(fa[u][i]!=fa[v][i]){
            u=fa[u][i];
            v=fa[v][i];
        }
    }
    return fa[u][0];
}
ll c[MAXN],C[MAXN];
ll num[MAXN],ns;
ll how_many[MAXN];
void M(ll pos){
    pos=p[pos];
    how_many[pos]++;
    if(how_many[pos]%2){
        num[c[pos]]--;
        if(num[c[pos]]==0){
            ns--;
        }
        return;
    }
    num[c[pos]]++;
    if(num[c[pos]]==1){
        ns++;
    }
}
unordered_map<ll,ll>ma;
ll n,m;
ll id[MAXN];
ll ans[MAXN];
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;++i){
        cin>>c[i];
        C[i]=c[i];
    }
    sort(C+1,C+n+1);
    ll tot=0;
    for(int i=1;i<=n;++i){
        if(!ma[C[i]]){
            ma[C[i]]=++tot;
        }
    }
    for(int i=1;i<=n;++i){
        c[i]=ma[c[i]];
    }
    for(int i=1;i<n;++i){
        ll u,v;
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1,0);
    ll len=pow(sz,0.5);
    ll many=sz/len;
    for(int i=1;i<=many;++i){
        for(int j=(i-1)*len+1;j<=i*len;++j){
            id[j]=i;
        }
    }
    for(int i=many*len+1;i<=sz;++i){
        id[i]=many+1;
    }
    for(int i=1;i<=m;++i){
        ll u,v;
        cin>>u>>v;
        if(s[u]>s[v]){
            swap(u,v);
        }
        q[i].time=i;
        q[i].lca=lca(u,v);
        if(q[i].lca==u){
            q[i].l=s[u];
            q[i].r=s[v];
            q[i].lca=0;
        }else{
            q[i].l=e[u];
            q[i].r=s[v];
        }
        q[i].kl=id[q[i].l];
        q[i].kr=id[q[i].r];
    }
    sort(q+1,q+m+1);
    ll l=1,r=0;
    for(int i=1;i<=m;++i){
        while(l>q[i].l){M(--l);}
        while(r<q[i].r){M(++r);}
        while(l<q[i].l){M(l++);}
        while(r>q[i].r){M(r--);}
        if(q[i].lca){M(q[i].lca);}
        ans[q[i].time]=ns;
        if(q[i].lca){M(q[i].lca);}
    }
    for(int i=1;i<=m;++i){
        cout<<ans[i]<<endl;
    }
    return 0;
}
2024/1/21 13:52
加载中...