分块求助(悬关)
查看原帖
分块求助(悬关)
983702
lrj3247楼主2024/8/8 11:12
#include <bits/stdc++.h>
const int N=2e5+15,M=1e3+15;
using namespace std;
int n,q,a[N],L,R,pos[N],len,m,ans;//m个块 
vector <int> la[M];
inline int read(){
	int w=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while('0'<=ch&&ch<='9'){
		w=w*10+ch-'0';
		ch=getchar();
	}
	return w*f;
}
inline void write(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
int MIN(int b1,int b2,int b3){
	if(b1<=b2&&b1<=b3) return b1;
	else if(b2<=b1&&b2<=b3) return b2;
	else return b3;
}
int minn(int x,int mb){
	int l=0,r=len-1,ret=0;
	while(l<=r){
		int mid=l+r>>1;
		if(la[x][mid]<mb){
			ret=mid;
			l=mid+1;
		}
		else{
			r=mid-1;
		}
	}
	++ret;
	return ret;
}
int maxx(int x,int mb){
	int l=0,r=len-1,ret=len+1;
	while(l<=r){
		int mid=l+r>>1;
		if(la[x][mid]>mb){
			ret=mid;
			r=mid-1;
		}
		else{
			l=mid+1;
		}
	}
	++ret;
	return len-ret+1;//最后一个块不用考虑,因为最右边也就是r也就是暴力。 
}
int mq(int l,int r){
	int ret=0,lr=min(n,pos[l]*len),rl=min(n,(pos[r]-1)*len+1);//想一想 
	if(rl<=l) rl=l+1;
	if(lr>=r) lr=r-1;
	for(int i = l+1 ; i<=lr ; i++){
		if(a[i]>a[r]) --ret;
		if(a[i]<a[r]) ++ret;
		if(a[i]<a[l]) --ret;
		if(a[i]>a[l]) ++ret;
	}
	for(int i = rl ; i<r ; i++){
		if(a[i]>a[r]) --ret;
		if(a[i]<a[r]) ++ret;
		if(a[i]<a[l]) --ret;
		if(a[i]>a[l]) ++ret;
	}
	for(int i = pos[l]+1 ; i<pos[r] ; i++){
		ret+=minn(i,a[r]);
		ret-=maxx(i,a[r]);
		ret+=maxx(i,a[l]);
		ret-=minn(i,a[l]);
	}
	int xbl=lower_bound(la[pos[l]].begin(),la[pos[l]].end(),a[l])-la[pos[l]].begin(),xbr=lower_bound(la[pos[r]].begin(),la[pos[r]].end(),a[r])-la[pos[r]].begin();
	swap(la[pos[l]][xbl],la[pos[r]][xbr]);
	swap(a[l],a[r]);
	if(a[l]>a[r]) ++ret;//已经修改了
	else if(a[l]<a[r]) --ret;
	sort(la[pos[l]].begin(),la[pos[l]].end());
	sort(la[pos[r]].begin(),la[pos[r]].end());
	return ret;
}
int main(){
	n=read(),q=read(),len=sqrt(n);
	for(int i = 1 ; i<=n ; i++){
		a[i]=i;
		pos[i]=(i-1)/len+1;
		la[pos[i]].push_back(a[i]);
	}
	m=pos[n];
	for(int i = 1 ; i<=m ; i++){
		sort(la[i].begin(),la[i].end());
	}
	while(q--){
		L=read(),R=read();
		if(L>R) swap(L,R);
		ans+=mq(L,R);
		write(ans);
		putchar('\n');
//		for(int i = 1 ; i<=n ; i++) cout<<a[i]<<" ";
//		cout<<endl;
	}
	return 0;
}
/*6 1
1 6*/
2024/8/8 11:12
加载中...