莫队拆询问30ptsWA求调
查看原帖
莫队拆询问30ptsWA求调
792049
vegetable_chili楼主2024/4/2 08:43

看之前好多人也和我一样,想请教一下错误的原因。

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x=0,f=1;
    char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
void write(int x){
    if(x<0){putchar('-');x=-x;}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
struct node{
	int x,id;
	bool operator<(const node& y)const{return x<y.x;}
}a[100005];
int n,m,u,v,num,tot,tmp,tp,rk[100005],b[100005],op,x,y,cnt[100005][2],root=1,block;
long long out[500005],ans;
vector<pair<int,int> >vv;
struct que{
	int l,r,w,id;
	bool operator<(const que& x)const{
		if(l/block!=x.l/block)return l<x.l;
		return r<x.r;
	}
}q[8000005];
int e,hd[100005],dfn[100005],lst[100005];
struct edge{int v,nxt;}g[200005];
inline void build(const int& u,const int& v){g[++e]=(edge){v,hd[u]};hd[u]=e;}
void dfs(const int& u,const int& fa){//求dfs序 
	dfn[u]=++tmp;
	b[tmp]=rk[u];
	for(register int i=hd[u];i;i=g[i].nxt){
		int v=g[i].v;
		if(v==fa)continue;
		dfs(v,u);
	}
	lst[u]=tmp;
}
inline void find(const int& x,vector<pair<int,int> >& vv){//找到x的子树在dfs序中的范围 
	vv.clear();
	if(x==root)vv.push_back(make_pair(1,n));//为根就是整个序列 
	else if(dfn[x]<dfn[root]&&dfn[root]<=lst[x]){//根在x子树内,拆成两半 
		vv.push_back(make_pair(1,dfn[x]));
		if(lst[x]<n)vv.push_back(make_pair(lst[x]+1,n));
	}else vv.push_back(make_pair(dfn[x],lst[x]));//根在x子树外 
}
inline void push(int l,const int& r,int x,const int& y){//再次拆询问,差分 
	l--,x--;
	if(l&&x)q[++tot]=(que){l,x,1,num};
	if(l)q[++tot]=(que){l,y,-1,num};
	if(x)q[++tot]=(que){r,x,-1,num};
	q[++tot]=(que){r,y,1,num};
}
//下面是维护每个数出现的次数以及答案 
inline void add(const int& x,const int& id){
	cnt[b[x]][id]++;
	ans+=cnt[b[x]][id^1];
}
inline void del(const int& x,const int& id){
	cnt[b[x]][id]--;
	ans-=cnt[b[x]][id^1];
}
inline void MoCap(){//莫队 
	int l=0,r=0;
	for(register int i=1;i<=tot;i++){
		while(l<q[i].l)add(++l,0);
		while(l>q[i].l)del(l--,0);
		while(r<q[i].r)add(++r,1);
		while(r>q[i].r)del(r--,1);
		out[q[i].id]+=q[i].w*ans;
	}
}
signed main(){
	n=read(),m=read();
	block=sqrt(n);
	for(register int i=1;i<=n;i++)a[i]=(node){read(),i};
	sort(a+1,a+n+1);
	for(register int i=1;i<=n;i++){//离散化 
		if(a[i].x!=a[i-1].x)tp++;
		rk[a[i].id]=tp;
	}
	for(register int i=1;i<n;i++){
		u=read(),v=read();
		build(u,v);
		build(v,u);
	}
	dfs(root,0);
	for(register int i=1;i<=m;i++){
		op=read();
		if(op==1)root=read();
		else{
			x=read(),y=read(),num++;
			vector<pair<int,int> >v1,v2;
			find(x,v1);find(y,v2);
			for(register int j=0;j<v1.size();j++){
				for(register int k=0;k<v2.size();k++){
					push(v1[j].first,v1[j].second,v2[k].first,v2[k].second);
				}
			}
		}
	}
	for(register int i=1;i<=tot;i++)if(q[i].l>q[i].r)swap(q[i].l,q[i].r);
	sort(q+1,q+tot+1);
	MoCap();
	for(register int i=1;i<=num;i++){
		write(out[i]);putchar('\n');
	}
}
2024/4/2 08:43
加载中...