情况一 | 将x与y调换后,会增加[x+1,y-1]中比x大的数的个数个逆序对 |
---|---|
情况二 | 将x与y调换后,会减少[x+1,y-1]中比x小的数的个数个逆序对 |
情况三 | 将x与y调换后,会减少[x+1,y-1]中比y大的数的个数个逆序对 |
情况四 | 将x与y调换后,会增加[x+1,y-1]中比y小的数的个数个逆序对 |
#include <map>//大爷给开的库不敢删
#include <set>//大爷给开的库不敢删
#include <cmath>//大爷给开的库不敢删
#include <queue>//大爷给开的库不敢删
#include <vector>//大爷给开的库不敢删
#include <cstdio>//大爷给开的库不敢删
#include <cstring>//大爷给开的库不敢删
#include <iomanip>//大爷给开的库不敢删
#include <iostream>//大爷给开的库不敢删
#include <algorithm>//大爷给开的库不敢删
#define N 320100
#define M 5000100
#define K 20010
#define INF 0x3f3f3f3f
using namespace std ;
struct node
{
int l,r,w,v,size,rnd;
}tr[M];
int n,m,size,ans,tot;
int a[N],root[K];
void make_new(int k)
{
tr[k].size = tr[tr[k].l].size + tr[tr[k].r].size + tr[k].w ;
}
void lturn(int &k)
{
int t = tr[k].r ;
tr[k].r = tr[t].l ;
tr[t].l = k ;
tr[t].size = tr[k].size ;
make_new(k) ;
k = t ;
}
void rturn(int &k)
{
int t = tr[k].l ;
tr[k].l = tr[t].r ;
tr[t].r = k ;
tr[t].size = tr[k].size ;
make_new(k) ;
k = t ;
}
void insert(int &k , int x)
{
if(!k)
{
k = ++size ;
tr[k].size = tr[k].w = 1 ;
tr[k].v = x ;
tr[k].rnd = rand() ;
return ;
}
tr[k].size ++ ;
if(tr[k].v==x){tr[k].w++;return;}
if(x<tr[k].v){insert(tr[k].l,x);if(tr[tr[k].l].rnd<tr[k].rnd){rturn(k);}}
else{insert(tr[k].r,x);if(tr[tr[k].r].rnd<tr[k].rnd){lturn(k);}}
}
void del(int &k , int x)
{
if(tr[k].v==x)
{
if(tr[k].w>1){tr[k].w--;tr[k].size--;return;}
if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r;
else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd){rturn(k);del(k,x);}
else{lturn(k);del(k,x);}
}
else if(x<tr[k].v){del(tr[k].l,x);tr[k].size--;}
else{del(tr[k].r,x);tr[k].size--;}
}
void build(int k,int l,int r,int x,int num)
{
insert(root[k],num) ;
if(l==r)return ;
int mid = (l+r)>>1 ;
if(x<=mid)build(k<<1,l,mid,x,num);
else build(k<<1|1,mid+1,r,x,num);
}
void tr_rk_min(int k,int x)
{
if(!k)return;
if(tr[k].v==x){ans+=tr[tr[k].l].size;return;}
else if(x<tr[k].v)tr_rk_min(tr[k].l,x);
else{ans+=tr[tr[k].l].size+tr[k].w;tr_rk_min(tr[k].r,x);}
}
void a_rk_min(int k,int l,int r,int L,int R,int x)
{
if(L==l&&R==r){tr_rk_min(root[k],x);return;}
int mid=(l+r)>>1;
if(mid>=R)a_rk_min(k<<1,l,mid,L,R,x);
else if(mid<L)a_rk_min(k<<1|1,mid+1,r,L,R,x);
else
{
a_rk_min(k<<1,l,mid,L,mid,x);
a_rk_min(k<<1|1,mid+1,r,mid+1,R,x);
}
}
void tr_rk_max(int k,int x)
{
if(!k)return;
if(tr[k].v==x){ans+=tr[tr[k].r].size;return;}
else if(x<tr[k].v){ans+=tr[tr[k].r].size+tr[k].w;tr_rk_max(tr[k].l,x);}
else{tr_rk_max(tr[k].r,x);}
}
void a_rk_max(int k,int l,int r,int L,int R,int x)
{
if(L==l&&R==r){tr_rk_max(root[k],x);return;}
int mid=(l+r)>>1;
if(mid>=R)a_rk_max(k<<1,l,mid,L,R,x);
else if(mid<L)a_rk_max(k<<1|1,mid+1,r,L,R,x);
else
{
a_rk_max(k<<1,l,mid,L,mid,x);
a_rk_max(k<<1|1,mid+1,r,mid+1,R,x);
}
}
void update(int k,int l,int r,int x,int num,int y)
{
del(root[k],y);
insert(root[k],num);
if(l==r)return;
int mid=(l+r)>>1;
if(x<=mid)update(k<<1,l,mid,x,num,y);
else update(k<<1|1,mid+1,r,x,num,y);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)build(1,1,n,i,a[i]);
for(int i=1;i<=n-1;i++)
{
ans=0;a_rk_min(1,1,n,i+1,n,a[i]);
tot+=ans;
}
printf("%d\n",tot) ;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(x==y||a[x]==a[y]){printf("%d\n",tot);continue;}
if(x>y)swap(x,y);
if(x+1!=y)
{
ans=0;a_rk_max(1,1,n,x+1,y-1,a[x]);tot+=ans;
ans=0;a_rk_min(1,1,n,x+1,y-1,a[x]);tot-=ans;
ans=0;a_rk_max(1,1,n,x+1,y-1,a[y]);tot-=ans;
ans=0;a_rk_min(1,1,n,x+1,y-1,a[y]);tot+=ans;
}
if(a[x]<a[y])tot++;
else tot--;
update(1,1,n,x,a[y],a[x]);
update(1,1,n,y,a[x],a[y]);
swap(a[x],a[y]);
printf("%d\n",tot) ;
}
}
原文地址:http://blog.csdn.net/wzq_qwq/article/details/46045385