排队
线段树套动态开点的权值线段树。区间查询值域的元素数量,用树套树维护即可。虽然可以用暴力水过去,但还是试一下吧。震惊的是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;
}
一如既往,万事胜意