排队

link

线段树套动态开点的权值线段树。区间查询值域的元素数量,用树套树维护即可。虽然可以用暴力水过去,但还是试一下吧。震惊的是a和b的大小关系是不一定的,调了半天不明所以。很悲惨。

#include<bits/stdc++.h>
//#define feyn
using namespace std;
const int N=20010;
const int M=3000010;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}
inline void swap(int &s1,int &s2){
	int s3=s1;s1=s2;s2=s3;return;
}

int m,n,num,a[N],b[N];

namespace x{
	#define lc t[wh].left
	#define rc t[wh].right
	#define mid (l+r>>1)
	struct node{
		int left,right,data;
	}t[M];
	int cnt,rr[N<<2];
	inline void change(int &wh,int l,int r,int pl,int val){
		if(wh==0)wh=++cnt;t[wh].data+=val;
		if(l==r)return;
		if(pl<=mid)change(lc,l,mid,pl,val);
		else change(rc,mid+1,r,pl,val);
	}
	inline int work(int wh,int l,int r,int wl,int wr){
		if(wl>wr||wh==0)return 0;
		if(wl<=l&&r<=wr)return t[wh].data;
		int an=0;
		if(wl<=mid)an+=work(lc,l,mid,wl,wr);
		if(wr>mid)an+=work(rc,mid+1,r,wl,wr);
		return an;
	}
	inline void update(int wh,int v1,int v2){
		if(v1)change(rr[wh],1,num,v1,-1);
		change(rr[wh],1,num,v2,1);
	}
	#undef lc
	#undef rc
	#undef mid
}
namespace y{
	#define lc (wh<<1)
	#define rc (wh<<1|1)
	#define mid (t[wh].l+t[wh].r>>1)
	struct node{
		int l,r;
	}t[N<<2];
	inline void build(int wh,int l,int r){
		t[wh].l=l,t[wh].r=r;
		if(l==r)return;
		build(lc,l,mid);
		build(rc,mid+1,r);
	}
	inline void change(int wh,int pl,int v1,int v2){
		x::update(wh,v1,v2);
		if(t[wh].l==t[wh].r)return;
		change(pl<=mid?lc:rc,pl,v1,v2);
	}
	inline int work(int wh,int wl,int wr,int ql,int qr){
		if(wl>wr)return 0;
		if(wl<=t[wh].l&&t[wh].r<=wr){
			return x::work(x::rr[wh],1,num,ql,qr);
		}
		int an=0;
		if(wl<=mid)an+=work(lc,wl,wr,ql,qr);
		if(wr>mid)an+=work(rc,wl,wr,ql,qr);
		return an;
	}
	#undef lc
	#undef rc
	#undef mid
}

namespace z{
	#define lowbit (wh&-wh)
	int t[N];
	inline void change(int wh){
		for(;wh<=num;wh+=lowbit)t[wh]++;
	}
	inline int work(int wh){
		int an=0;
		for(;wh;wh-=lowbit)an+=t[wh];
		return an;
	}
	#undef lowbit
}


signed main(){
	
	#ifdef feyn
	freopen("in.txt","r",stdin);
	#endif
	
	read(m);
	for(int i=1;i<=m;i++)read(a[i]),b[i]=a[i];
	sort(b+1,b+m+1);num=unique(b+1,b+m+1)-b-1;
	for(int i=1;i<=m;i++)a[i]=upper_bound(b+1,b+num+1,a[i])-b-1;
	y::build(1,1,m);int s1,s2,ans=0;
	for(int i=m;i;i--)ans+=z::work(a[i]-1),z::change(a[i]);
	printf("%d\n",ans);read(n);
	for(int i=1;i<=m;i++)y::change(1,i,0,a[i]);
	for(int i=1;i<=n;i++){
		read(s1);read(s2);
		if(s1>s2)swap(s1,s2);
		ans-=y::work(1,s1+1,s2-1,1,a[s1]-1);
		ans-=y::work(1,s1+1,s2-1,a[s2]+1,num);
		ans+=y::work(1,s1+1,s2-1,a[s1]+1,num);
		ans+=y::work(1,s1+1,s2-1,1,a[s2]-1);
		if(a[s1]>a[s2])ans--;
		if(a[s1]<a[s2])ans++;
		y::change(1,s1,a[s1],a[s2]);
		y::change(1,s2,a[s2],a[s1]);
		swap(a[s1],a[s2]);
		printf("%d\n",ans);
	}
	
	return 0;
}
posted @ 2022-07-22 18:45  Feyn618  阅读(18)  评论(0编辑  收藏  举报