蒟蒻求助分块
查看原帖
蒟蒻求助分块
383791
Others楼主2021/11/26 13:54

WA 了几个点,调了一周了,求 dalao 帮忙调一下。

#include <bits/stdc++.h>
using namespace std;
void qr(int &x){
	int f=x=0;
	char c=getchar();
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
	x=f?~(x-1):x;
}
const int N=100005,Sn=205;
int rt[Sn][N],fa[N],a[N],cnt[N],ccnt[Sn],n,m,s,bls,L[Sn],R[Sn],Ls[Sn],Rs[Sn],blss,ss,idx[N],idxx[N],Maxa,numc[Sn][N],nums[Sn][Sn],opt,l,r,x,y,temp,Tmp[N],top;
inline void merge(int p,int x,int y){
	if(rt[p][x]==0) return;
	if(rt[p][y]) fa[rt[p][x]]=rt[p][y];
	else a[rt[p][x]]=y,rt[p][y]=rt[p][x];
	rt[p][x]=0;
}
int get(int x){
	return fa[x]==x?x:fa[x]=get(fa[x]);
}
inline void update(int bl,int l,int r,int x,int y){
	rt[bl][x]=rt[bl][y]=top=temp=0;
	for(int i=L[bl];i<=R[bl];i++) {
		a[i]=a[get(i)];
		if(a[i]==x||a[i]==y) Tmp[++top]=i;
	}
	for(int i=l;i<=r;i++){
		if(a[i]==x) a[i]=y,++temp;
	}
	for(int i=1;i<=top;i++){
		if(!rt[bl][a[Tmp[i]]]) rt[bl][a[Tmp[i]]]=Tmp[i];
		fa[Tmp[i]]=rt[bl][a[Tmp[i]]];
	}
	for(int i=bl;i<=bls;i++) numc[i][x]-=temp,numc[i][y]+=temp,nums[i][idxx[x]]-=temp,nums[i][idxx[y]]+=temp;
	return ;
}
int main() {
//	freopen("cyy.in","r",stdin);
//	freopen("PPP.out","w",stdout);
	qr(n),qr(m);
	s=600,bls=(n+s-1)/s;
	for(int i=1;i<=bls;i++){
		L[i]=R[i-1]+1,R[i]=min(s*i,n);
		for(int j=L[i];j<=R[i];j++) idx[j]=i;
	} 
	Maxa=1e5;
	for(int i=1;i<=n;i++){
		qr(a[i]);
	}
	ss=600,blss=(1e5+ss-1)/ss;
	for(int i=1;i<=blss;i++){
		Ls[i]=Rs[i-1]+1,Rs[i]=min(ss*i,Maxa);
		for(int j=Ls[i];j<=Rs[i];j++) idxx[j]=i;
	} 
	for(int i=1;i<=bls;i++){
		for(int j=L[i];j<=R[i];j++){
			if(rt[i][a[j]]==0) rt[i][a[j]]=j;
			fa[j]=rt[i][a[j]];
			for(int k=i;k<=bls;k++) ++numc[k][a[j]],++nums[k][idxx[a[j]]];
		}
	}
	while(m--){
		qr(opt);
		if(opt==1){
			qr(l),qr(r),qr(x),qr(y);
			int lb=idx[l],rb=idx[r];
			if(lb==rb){
				update(lb,l,r,x,y);
				continue;
			}
			++lb,--rb;
			temp=numc[rb][x]-numc[lb-1][x];
			for(int i=lb;i<=rb;i++) {
				merge(i,x,y);
				nums[i][idxx[y]]+=numc[i][x]-numc[lb-1][x];
				nums[i][idxx[x]]-=numc[i][x]-numc[lb-1][x];
				numc[i][y]+=numc[i][x]-numc[lb-1][x];
				numc[i][x]=numc[lb-1][x];
			}
			for(int i=rb+1;i<=bls;i++) numc[i][x]-=temp,nums[i][idxx[x]]-=temp,numc[i][y]+=temp,nums[i][idxx[y]]+=temp;
			++rb,--lb;
			update(lb,l,R[lb],x,y);
			update(rb,L[rb],r,x,y);
		}else{
			qr(l),qr(r),qr(x);
			int lb=idx[l],rb=idx[r];
			if(lb==rb){
				for(int i=l;i<=r;i++) cnt[a[get(i)]]++,ccnt[idxx[a[get(i)]]]++;
				for(int i=1;i<=blss;i++){
					if(x>ccnt[i]) x-=ccnt[i];
					else{
						for(int j=Ls[i];j<=Rs[i];j++){
							if(x>cnt[j]) x-=cnt[j];
							else{
								printf("%d\n",j);
								break;
							}
						}
						break;
					}
				}
				for(int i=l;i<=r;i++) cnt[a[get(i)]]=ccnt[idxx[a[get(i)]]]=0;
				continue;
			}
			++lb,--rb;
			for(int i=l;i<L[lb];i++) ++cnt[a[get(i)]],++ccnt[idxx[a[get(i)]]];
			for(int i=R[rb]+1;i<=r;i++) ++cnt[a[get(i)]],++ccnt[idxx[a[get(i)]]];
			for(int i=1;i<=blss;i++) {
				if(x>nums[rb][i]-nums[lb-1][i]+ccnt[i]) x-=nums[rb][i]-nums[lb-1][i]+ccnt[i];
				else{
					for(int j=Ls[i];j<=Rs[i];j++){
						if(x>numc[rb][j]-numc[lb-1][j]+cnt[j]) x-=numc[rb][j]-numc[lb-1][j]+cnt[j];
						else{
							printf("%d\n",j);
							break;
						}
					}
					break;
				}
			}
			for(int i=l;i<L[lb];i++) cnt[a[get(i)]]=ccnt[idxx[a[get(i)]]]=0;
			for(int i=R[rb]+1;i<=r;i++) cnt[a[get(i)]]=ccnt[idxx[a[get(i)]]]=0;
		}
	}
	return 0;
}
2021/11/26 13:54
加载中...