蜜汁RE原理求教
查看原帖
蜜汁RE原理求教
100325
peterwuyihong楼主2021/6/29 21:54
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr<<#x<<' '<<x<<endl
#ifndef ONLINE_JUDGE
	#define pia getchar
#else
	#define pia nc
#endif
char nc(){
  	static char buf[1<<25],*p=buf,*q=buf;
  	if(p==q&&(q=(p=buf)+fread(buf,1,1<<25,stdin),p==q))return EOF;
  	return *p++;
}
template<class T>void rd(T&x){
	short f=1;x=0;
	char ch=pia();
	while(!isdigit(ch)){
		if(ch=='-')f=-1;
		ch=pia();
	}while(isdigit(ch)){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=pia();
	}x*=f;
}
template<class T>void wr(T x){
	if(x<0)putchar('-'),x=-x;
	if(x>=10)wr(x/10);
	putchar(x%10+48);
}

#define maxn 100010
int n,m,lstans,lim;
int a[maxn];
int val[maxn];
int app[maxn];
int id[maxn],tot;
int ans[320][maxn];
vector<int>v[maxn];
void build(int x){
	if(id[x]==0)id[x]=++tot;
	memset(ans[id[x]],0x3f,sizeof ans[id[x]]);
	v[x].clear();
	int dis=INT_MAX;
	for(int i=1;i<=n;i++){
		if(a[i]==x)dis=0;
		else dis++;
		ans[id[x]][a[i]]=min(ans[id[x]][a[i]],dis);
	}
	dis=INT_MAX;
	for(int i=n;i;i--){
		if(a[i]==x)dis=0;
		else dis++;
		ans[id[x]][a[i]]=min(ans[id[x]][a[i]],dis);
	}
}
void merge(int x,int y){
	vector<int>ans;
	int i=0,j=0;
	while(i<v[x].size()&&j<v[y].size())
	if(v[x][i]<v[y][j])ans.push_back(v[x][i++]);
	else ans.push_back(v[y][j++]);
	while(i<v[x].size())ans.push_back(v[x][i++]);
	while(j<v[y].size())ans.push_back(v[y][j++]);
	v[y]=ans;
}
void bf1(int x,int y){
	for(int i=0;i<v[x].size();i++)a[v[x][i]]=y;
	for(int i=1;i<=tot;i++)ans[i][y]=min(ans[i][y],ans[i][x]);
	merge(x,y);
}
void bf2(int x,int y){
	for(int i=1;i<=n;i++)if(a[i]==x)a[i]=y;
	build(y);
}
void change(int x,int y){
	if(app[val[x]]==0||val[x]==val[y])return;
	int px=val[x],py=val[y];
	if(app[px]>app[py])val[y]=val[x],swap(px,py);
	val[x]=0,x=px,y=py;
	if(!x||!y)return;
	if(app[x]<=lim&&app[y]<=lim){
		if(app[x]+app[y]<=lim)bf1(x,y);
		else bf2(x,y);
	}
	if(app[x]<=lim&&app[y]>lim){
		if(app[x]+v[y].size()<=lim)bf1(x,y);
		else bf2(x,y);
	}
	if(app[x]>lim)bf2(x,y);
	app[y]+=app[x],app[x]=0;
	v[x].clear();
}
int calc(int x,int y){
	int i=0,j=0,ans=INT_MAX;
	if(!app[x]||!app[y])return ans;
	while(i<v[x].size()&&j<v[y].size())
	if(v[x][i]<v[y][j])ans=min(ans,v[y][j]-v[x][i++]);
	else ans=min(ans,v[x][i]-v[y][j++]);
	return ans;
}
int ask(int x,int y){
	x=val[x],y=val[y];
	if(!x||!y||!app[x]||!app[y])return -1;
	if(x==y)return 0;
	if(app[x]>app[y])swap(x,y);
	if(app[x]<=lim&&app[y]<=lim)return calc(x,y);
	if(app[x]<=lim&&app[y]>lim)return min(calc(x,y),ans[id[y]][x]);
	if(app[x]>lim)return min(calc(x,y),min(ans[id[y]][x],ans[id[x]][y]));
	return -1;
}
int opt,x,y;
signed main(){
#ifndef ONLINE_JUDGE
	freopen("testdata.in","r",stdin);
#endif
	rd(n),rd(m);
	for(int i=1;i<=n;i++)rd(a[i]);
	lim=sqrt(n);
	for(int i=1;i<=n;i++)app[a[i]]++,v[a[i]].push_back(i),val[a[i]]=a[i];
	for(int i=1;i<=n;i++)if(app[i]>lim)build(i);
	while(m--){
		rd(opt),rd(x),rd(y);
		x^=lstans,y^=lstans;
		if(x>n||y>n)exit(0);
		if(opt==1)change(x,y);
		else{
			lstans=ask(x,y);
			if(lstans==-1)lstans++,puts("Ikaros");
			else wr(lstans),putchar('\n');
		}
	}
#ifndef ONLINE_JUDGE
	cerr<<endl<<(double)clock()/CLOCKS_PER_SEC;
#endif
}

加上一个全局define int long longdefine\ int\ long\ long就过了,十分神奇,不晓得原理

2021/6/29 21:54
加载中...