小菜鸡莫队 $O(n\log n\sqrt n)$ T了qaq
查看原帖
小菜鸡莫队 $O(n\log n\sqrt n)$ T了qaq
35891
huangzirui楼主2020/10/30 10:13

RT.

#include <bits/stdc++.h>
#define ll long long
#define Mid ((L+R)>>1)
using namespace std;
typedef pair<int,int> pii;
inline int read(){
	char c;int x=0;int b=1;do{c=getchar();if(c==45)b=-1;}while(c>57||c<48);
	do x=x*10+c-48,c=getchar();while(c<=57&&c>=48);x*=b;return x;
}
const int maxn=200010;
int i,j,k,n,m,a[maxn],block[maxn],ans[maxn],N;
struct node{
	int x,y,id;
}ask[maxn];
int cmp(node a,node b){
	return block[a.x]==block[b.x]?
				block[a.y]==block[b.y]?
					(a.id<b.id):
				(a.y<b.y):
			a.x<b.x;
}
namespace segment_tree{
	int tree[maxn*4];
	int lowbit(int x){return x&(-x);}
	void add(int x,int s){
		for(;x<=n+1;x+=lowbit(x))tree[x]+=s;
	}
	int find(int x){
		int s=0;for(;x;x-=lowbit(x))s+=tree[x];return s;
	}
	/*
	inline void update(int root){tree[root]=tree[root*2]+tree[root*2+1];}
	void add(int root,int L,int R,int x,int s){
		if(L==R){
			tree[root]+=s;
			return;
		}
		if(x<=Mid)add(root*2,L,Mid,x,s);
		else add(root*2+1,Mid+1,R,x,s);
		update(root);
	}
	int find(int root,int L,int R,int l,int r){
		if(L==l && R==r)return tree[root];
		if(r<=Mid)return find(root*2,L,Mid,l,r);
		else if(l>Mid)return find(root*2+1,Mid+1,R,l,r);
		else return find(root*2,L,Mid,l,Mid)+find(root*2+1,Mid+1,R,Mid+1,r);
	}
	*/
}using namespace segment_tree;
inline void insert(int x){
	add(a[x],1);
	return;
}
inline void delate(int x){
	add(a[x],-1);
	return;
}
int l=1,r=0,c=0,X[maxn],Y[maxn];
void add_c(int x){
	int A=X[x],B=Y[x];
	bool b1=(l<=A && A<=r),b2=(l<=B && B<=r);
	if(b1 && !b2){
		add(a[B],1);
		add(a[A],-1);
	}else
	if(b2 && !b1){
		add(a[A],1);
		add(a[B],-1);
	}swap(a[A],a[B]);
}
int main() {
	freopen("CF785E.in","r",stdin);
	freopen("CF785E.out","w",stdout);
	n=read();m=read();N=pow(n,0.66);
	for(i=1;i<=n;i++)a[i]=i,block[i]=(i-1)/N+1;
	for(i=1;i<=m;i++){
		int x=read(),y=read();
		if(x>y)swap(x,y);
		X[i]=x;Y[i]=y;
		ask[i]={x,y,i-1};
	}sort(ask+1,ask+1+m,cmp);
	for(i=1;i<=m;i++){
		while(r<ask[i].y)insert(++r);
		while(r>ask[i].y)delate(r--);
		while(l>ask[i].x)insert(--l);
		while(l<ask[i].x)delate(l++);
		while(c<ask[i].id)add_c(++c);
		while(c>ask[i].id)add_c(c--);
		int x=ask[i].x,y=ask[i].y;
		if(x!=y)
			ans[ask[i].id]=(a[x]>a[y]?(-1-2*(find(a[x]-1)-find(a[y]))):
									   (1+2*(find(a[y]-1)-find(a[x]))));
		else ans[ask[i].id]=0;
	}
	cout<<ans[0]<<endl;
	for(i=1;i<m;i++)ans[i]+=ans[i-1],printf("%d\n",ans[i]);
	//cerr << 1.0*clock()/CLOCKS_PER_SEC << endl;
	return 0;
}
2020/10/30 10:13
加载中...