求指点update函数的散块修改。
查看原帖
求指点update函数的散块修改。
1288642
lmn985楼主2025/6/23 20:17
#include <bits/stdc++.h>
#define left LEfT
#define right rIGhT
#define REP(i,a,b) for(int i=a;i>=b;i--)
#define rep(i,a,b) for(int i=a;i<b;i++)
char *p1,*p2,buf[200010];
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,200000,stdin),p1==p2)?EOF:*p1++)
inline int read(){
    register int x=0;
    char ch=0;
    while(!(ch>='0' and ch<='9'))ch=getchar();
    while(ch>='0' and ch<='9')x=x*10+ch-48,ch=getchar();
    return x;
}
inline void write(int x){
    if(x>9)write(x/10);
    putchar(x%10+'0');
    return;
}
using namespace std;
const int N=100005,B=230,X=436;
int n,m,a[N],le[X],ri[X],INF=1000000007;
int len,left[X][B+5],right[X][B+5],val[X][B+5];
short dis[X][B+5][B+5],id[N][X],pos[N],ll,rr;
inline void build_dis(int I){
	short res=0;
	rep(i,le[I],ri[I]+1)id[a[i]][I]=0;
	rep(i,le[I],ri[I]+1){
		if(id[a[i]][I]==0){
			id[a[i]][I]=++res;
			val[I][res]=a[i];
		}
		pos[i]=id[a[i]][I];
	}
	rep(i,le[I],ri[I]+1){
		rep(j,i,ri[I]+1){
			ll=min(pos[i],pos[j]),rr=max(pos[i],pos[j]);
			dis[I][ll][rr]=min((short)(j-i),dis[I][ll][rr]);
		}
		right[I][pos[i]]=i;
		if(left[I][pos[i]]==INF)left[I][pos[i]]=i;
	}
}
inline void build_pair(int I,short x){
	int last=-1;
	rep(i,le[I],ri[I]+1){
		if(pos[i]==x){
			last=i;
			left[I][x]=min(left[I][x],i);
			right[I][x]=max(right[I][x],i);
		}
		ll=min(pos[i],x),rr=max(pos[i],x);
		if(last!=-1)dis[I][ll][rr]=min(dis[I][ll][rr],(short)(i-last));
	}
	last=-1;
	REP(i,ri[I],le[I]){
		if(pos[i]==x)last=i;
		ll=min(pos[i],x),rr=max(pos[i],x);
		if(last!=-1)dis[I][ll][rr]=min((short)(last-i),dis[I][ll][rr]);
	}
}
inline void clearblock(int I,short X){
	left[I][id[X][I]]=INF,right[I][id[X][I]]=-INF;
	rep(i,X,B+1)dis[I][X][i]=10007;
	rep(i,1,X)dis[I][i][X]=10007;
}
inline void init(){
	rep(i,0,X)rep(j,0,B+5)left[i][j]=INF;
	rep(i,0,X)rep(j,0,B+5)right[i][j]=-INF;
	memset(le,0x3f,sizeof(le));
	memset(dis,0x3f,sizeof(dis));
	rep(i,0,n){
		ri[i/B]=i;
		if(le[i/B]>=10000000)le[i/B]=i;
	}
	len=(n-1)/B+1;
	rep(i,0,len)build_dis(i);
}
inline void update(int l,int r,int x,int y){
	if(x==y)return ;
	register int R1=min(r,ri[l/B])+1,L2=max(l,le[r/B]),bl=l/B,br=r/B;
	bool have1=0,have2=0;
	rep(i,l,R1)if(pos[i]==id[x][bl])have1=1;
	if(bl!=br)rep(i,L2,r+1)if(pos[i]==id[x][br])have2=1;
	rep(i,bl+1,br){
		if(id[x][i]==0)continue;
		if(id[y][i]==0)id[y][i]=id[x][i],val[i][id[x][i]]=y,id[x][i]=0;
		else{
			ll=id[x][i],rr=id[y][i];
			left[i][rr]=min(left[i][rr],left[i][ll]);
			right[i][rr]=max(right[i][rr],right[i][ll]);
			for(short j=1;j<=ri[i]-le[i]+1;j++)dis[i][min(j,rr)][max(j,rr)]=min(dis[i][min(j,rr)][max(j,rr)],dis[i][min(j,ll)][max(j,ll)]);
			rep(j,le[i],ri[i]+1)if(pos[j]==id[x][i])pos[j]=id[y][i];
			val[i][id[x][i]]=0,id[x][i]=0;
		}
	}
	if(have1){
		int poy=id[y][bl];
		if(poy==0)rep(i,1,ri[bl]-le[bl]+2)if(val[bl][i]==0){poy=i;break;}
		if(poy==0)id[y][bl]=id[x][bl],val[bl][id[x][bl]]=y,id[x][bl]=0;
		else{
		    id[y][bl]=poy;
			val[bl][poy]=y;
			clearblock(bl,id[x][bl]);
			clearblock(bl,id[y][bl]);
		    rep(i,l,R1)if(pos[i]==id[x][bl])pos[i]=poy;
		    build_pair(bl,id[x][bl]);
		    build_pair(bl,id[y][bl]);
		    bool flag=0;
		    rep(i,le[bl],ri[bl]+1)if(val[bl][pos[i]]==x)flag=1;
		    if(!flag)val[bl][id[x][bl]]=0,id[x][bl]=0;
		}
	}
	if(bl!=br&&have2){
		int poy=id[y][br];
		if(poy==0)rep(i,1,ri[br]-le[br]+2)if(val[br][i]==0){poy=i;break;}
		if(poy==0)id[y][br]=id[x][br],val[br][id[x][br]]=y,id[x][br]=0;
		else{
			id[y][br]=poy;
			val[br][poy]=y;
			clearblock(br,id[x][br]);
			clearblock(br,id[y][br]);
			rep(i,L2,r+1)if(pos[i]==id[x][br])pos[i]=poy;
			build_pair(br,id[x][br]);
			build_pair(br,id[y][br]);
			bool flag=0;
			rep(i,le[br],ri[br]+1)if(val[br][pos[i]]==x)flag=1;
		    if(!flag)val[br][id[x][br]]=0,id[x][br]=0;
		}
	}
}
int query(int l,int r,int x,int y){
	register int R1=min(r,ri[l/B])+1,L2=max(l,le[r/B]),bl=l/B,br=r/B;
	int ans=INF,lastx=-1,lasty=-1;
	rep(i,l,R1){
		if(pos[i]==id[x][bl])lastx=i;
		if(pos[i]==id[y][bl])lasty=i;
		if(lastx!=-1&&lasty!=-1)ans=min(ans,abs(lastx-lasty));
	}
	if(bl!=br){
		lastx=-1,lasty=-1;
		rep(i,L2,r+1){
			if(pos[i]==id[x][br])lastx=i;
			if(pos[i]==id[y][br])lasty=i;
			if(lastx!=-1&&lasty!=-1)ans=min(ans,abs(lastx-lasty));
		}
	}
	else return ans;
	lastx=-INF,lasty=-INF;
	if(right[bl][id[x][bl]]>=l)lastx=right[bl][id[x][bl]];
	if(right[bl][id[y][bl]]>=l)lasty=right[bl][id[y][bl]];
	rep(i,bl+1,br){
		ll=id[x][i],rr=id[y][i];
		if(!ll&&!rr)continue;
		if(ll)ans=min(ans,left[i][ll]-lasty);
		if(rr)ans=min(ans,left[i][rr]-lastx);
		if(ll)lastx=right[i][ll];
		if(rr)lasty=right[i][rr];
		if(ll&&rr&&dis[i][min(ll,rr)][max(ll,rr)]<=B)ans=min(ans,(int)(dis[i][min(ll,rr)][max(ll,rr)]));
	}
	if(left[br][id[x][br]]<=r)ans=min(ans,left[br][id[x][br]]-lasty);
	if(left[br][id[y][br]]<=r)ans=min(ans,left[br][id[y][br]]-lastx);
	return ans;
}
signed main(){
	n=read(),m=read();
	rep(i,0,n)a[i]=read();
	init();
	rep(i,0,m){
		int o,l,r,x,y;
		o=read(),l=read(),r=read(),x=read(),y=read();
		if(o==1)update(l-1,r-1,x,y);
		else{
			int ans=query(l-1,r-1,x,y);
			if(ans>n)ans=-1;
			if(ans!=-1)write(ans),putchar('\n');
			else puts("-1");
		}
	}
    return 0;
}
2025/6/23 20:17
加载中...