真没绷住
查看原帖
真没绷住
315205
Kniqht楼主2023/9/30 21:28

这份代码就WA了

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,color[N],ans,sz[N];
int h[N],e[N],ne[N],idx,p[N];
void add(int a,int b){
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
} 
void merge(int x,int y){
	if(x==y) return;
	if(sz[x]>sz[y]) swap(x,y);
	for(int i=h[x];~i;i=ne[i]){
		int j=e[i];
		ans-=color[j-1]==y;
		ans-=color[j+1]==y;
	}
	for(int i=h[x];~i;i=ne[i]){
		int j=e[i];
		color[j]=y;
		if(!ne[i]){
			ne[i]=h[y];	
			h[y]=h[x];
			/*
			这一块意思为:
			将x拼接在y前面
			之后将x变成y 
			*/ 
			break;
		}
	}
	h[x]=0;
	sz[y]+=sz[x];
	sz[x]=0;
}
int main(){
	memset(h,-1,sizeof(h)); 
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&color[i]);
		add(color[i],i);sz[color[i]]++;
		if(color[i]!=color[i-1]) ans++;
	}
	for(int i=0;i<=N-10;i++) p[i]=i; 
	while(m--){
		int op,x,y;scanf("%d",&op);
		if(op==1){
			scanf("%d%d",&x,&y);
			merge(p[x],p[y]);
			//p数组可以指鹿为马 
		}
		else printf("%d\n",ans);
	}
    return 0;
}	

这份就AC了

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,color[N],ans,sz[N];
int h[N],e[N],ne[N],idx,p[N];
void add(int a,int b){
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
} 
void merge(int &x,int &y){//注意要引用,这样能进行swap,而且所有x都变为了y,所以x没用了 
	if(x==y) return;
	if(sz[x]>sz[y]) swap(x,y);
	for(int i=h[x];~i;i=ne[i]){
		int j=e[i];
		ans-=color[j-1]==y;
		ans-=color[j+1]==y;
	}
	for(int i=h[x];~i;i=ne[i]){
		int j=e[i];
		color[j]=y;
		if(ne[i]==-1){
			ne[i]=h[y];	
			h[y]=h[x];
			/*
			这一块意思为:
			将x拼接在y前面
			之后将x变成y 
			*/ 
			break;
		}
	}
	h[x]=-1;
	sz[y]+=sz[x];
	sz[x]=0;
}
int main(){
	memset(h,-1,sizeof(h));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&color[i]);
		add(color[i],i);sz[color[i]]++;
		if(color[i]!=color[i-1]) ans++;
	}
	for(int i=0;i<=N-10;i++) p[i]=i; 	
	while(m--){
		int op,x,y;scanf("%d",&op);
		if(op==1){
			scanf("%d%d",&x,&y);
			merge(p[x],p[y]);
			//p数组可以指鹿为马 
		}
		else printf("%d\n",ans);
	}
    return 0;
}

就是改了一下h数组初始化0还是-1,理论上一样啊,为什么会有错呢

2023/9/30 21:28
加载中...