树上莫队求调
查看原帖
树上莫队求调
455558
Imiya楼主2022/3/25 22:14

rt,不知为何 RE 了 qwq

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=100100;
int n,m,dfn[N<<1],fir[N],sec[N],k,cnt[N],ccnt[N],bel[N<<1],fa[N][20],dis[N],col[N],lp=1,rp;
int to[N<<1],head[N],nex[N<<1],e_cnt;
bool vis[N];
void pre(int id,int dep){
    vis[id]=true;
    dis[id]=dep;
    dfn[++k]=id;
    fir[id]=k;
    for(int i=head[id];i;i=nex[i]){
        int nx=to[i];
        if(vis[nx])continue;
        fa[nx][0]=id;
        for(int j=1;j<20;j++)fa[nx][j]=fa[fa[nx][j-1]][j-1];
        pre(nx,dep+1);
    }
    dfn[++k]=id;
    sec[id]=k;
}
inline int lca(int u,int v){
    if(dis[u]<dis[v])swap(u,v);
    int y=dis[u]-dis[v];
    for(int j=0;y;y>>=1,j++)if(y&1)u=fa[u][j];
    if(u==v)return u;
    for(int j=19;j>=0;j--)if(fa[u][j]!=fa[v][j])u=fa[u][j],v=fa[v][j];
    return fa[u][0];
}
struct node{
    int l,r,id,lca,k;
    inline bool operator<(const node&b)const{
    	if(bel[l]!=bel[b.l])
    		if(bel[l]&1)return r>b.r;
    		else return r<b.r;
    	else return bel[l]<bel[b.l];
    }
}ask[N];
bool res[N];
inline int read(){
	int r=0,i=getchar();
	while(i<'0'||i>'9')i=getchar();
	while(i>='0'&&i<='9')r=(r<<1)+(r<<3)+(i^48),i=getchar();
	return r;
}
void init(){
    cin>>n>>m;
    int siz=(int)sqrt(n<<1);
    for(int i=1;i<=n;i++)col[i]=read();
    for(int i=1;i<=(n<<1);i++)bel[i]=(i-1)/siz;
    for(int i=1;i<n;i++){
        int u=read(),v=read();
        to[++e_cnt]=v;
        nex[e_cnt]=head[u];
        head[u]=e_cnt;
        to[++e_cnt]=u;
        nex[e_cnt]=head[v];
        head[v]=e_cnt;
    }
    pre(1,1);
    for(int i=1;i<=m;i++){
        int u=read(),v=read(),id=read();
        int LCA=lca(u,v);
//		cout<<u<<' '<<v<<' '<<LCA<<endl; 
        if(LCA==u||LCA==v)ask[i]={min(fir[u],fir[v]),max(fir[u],fir[v]),i,0,id};
        else ask[i]={min(sec[u],sec[v]),max(fir[u],fir[v]),i,LCA,id};
    }
    sort(ask+1,ask+m+1);
}
inline void insert(int id){
    if(!ccnt[dfn[id]])cnt[col[dfn[id]]]++;
    else cnt[col[dfn[id]]]--;
    ccnt[dfn[id]]++;
}
inline void erase(int id){
    ccnt[dfn[id]]--;
    if(ccnt[dfn[id]])cnt[col[dfn[id]]]++;
    else cnt[col[dfn[id]]]--;
}
inline bool get_ans(int L,int R,int LCA,int id){
    while(rp<R)insert(++rp);
    while(lp>L)insert(--lp);
    while(rp>R)erase(rp--);
    while(lp<L)erase(lp++);
//    for(int i=1;i<=n;i++)cout<<cnt[i]<<' ';cout<<endl;
//    for(int i=1;i<=n;i++)cout<<ccnt[i]<<' ';cout<<endl;
    return cnt[id]||(LCA&&col[LCA]==id);
}
int main(){
//    freopen("C://read.in","r",stdin);
    init();
//    for(int i=1;i<=n;i++)cout<<col[i]<<' ';cout<<endl;
//    for(int i=1;i<=n*2;i++)cout<<dfn[i]<<' ';cout<<endl;
//    for(int i=1;i<=m;i++)cout<<ask[i].l<<' '<<ask[i].r<<' '<<ask[i].lca<<' '<<ask[i].id<<endl;
    for(int i=1;i<=m;i++)res[ask[i].id]=get_ans(ask[i].l,ask[i].r,ask[i].lca,ask[i].k);
    for(int i=1;i<=m;i++)printf("%d",res[i]);
    return 0;
}
2022/3/25 22:14
加载中...