排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。
红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足i< j且hi>hj的(i,j)数量。
幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。
这道题一开始先离散化,用树状数组求逆序对(本蒟蒻不会归并排序),之后我们发现交换两个位置l,r,其实对它的答案的影响只关两个位置之间的数,xjb乱想,发现答案跟区间的值跟a[l]和a[r]的大小关系有关,那看到这个,便想到了分块2,那这题就解决了,注意交换之后记得维护就好了。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
struct node
{
int s,d;
}wy[20010];
bool cmp(node a,node b)
{
if(a.s>b.s)return false;
if(a.s<b.s)return true;
return 0;
}
int n,ans,a[20010],b[20010],s[20010],belong[20010],bl[20010],br[20010];
void ps(int x)
{
int l=bl[x],r=br[x];
for(int i=l;i<=r;i++)b[i]=a[i];
sort(b+l,b+r+1);
}
void fk()
{
int cnt=sqrt(n);
for(int i=1;i<=n;i++)
{
int bg=(i-1)/cnt+1;
belong[i]=bg;
if(bl[bg]==0)bl[bg]=i,br[bg-1]=i-1;
}
br[belong[n]]=n;
}
int fup(int x,int k)
{
int l=bl[x],r=br[x],ans=br[x]+1;
while(l<=r)
{
int mid=(l+r)/2;
if(b[mid]>k)ans=mid,r=mid-1;
else l=mid+1;
}
return br[x]-ans+1;
}
int fdown(int x,int k)
{
int l=bl[x],r=br[x],ans=bl[x]-1;
while(l<=r)
{
int mid=(l+r)/2;
if(b[mid]<k)ans=mid,l=mid+1;
else r=mid-1;
}
return ans-bl[x]+1;
}
int lowbit(int x){return x&-x;}
void add(int x,int k)
{
while(x<=n)
{
s[x]+=k;
x+=lowbit(x);
}
}
int getsum(int x)
{
int ans=0;
while(x>=1)
{
ans+=s[x];
x-=lowbit(x);
}
return ans;
}
inline void walk(int now,int x,int y)
{
if(a[now]>a[x])ans++;
if(a[now]<a[x])ans--;
if(a[now]>a[y])ans--;
if(a[now]<a[y])ans++;
}
void solve(int x,int y)
{
int bx=belong[x],by=belong[y];
if(a[x]<a[y])ans++;
if(a[x]>a[y])ans--;
if(bx==by)for(int i=x+1;i<y;i++)walk(i,x,y);
else
{
for(int i=x+1;i<=br[bx];i++)walk(i,x,y);
for(int i=bl[by];i<y;i++)walk(i,x,y);
for(int i=bx+1;i<by;i++)
{
ans+=fup(i,a[x])+fdown(i,a[y]);
ans-=fdown(i,a[x])+fup(i,a[y]);
}
}
}
int main()
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
int t,id=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&wy[i].s),wy[i].d=i;
sort(wy+1,wy+n+1,cmp);wy[0].s=0;
for(int i=1;i<=n;i++)
{
if(wy[i].s!=wy[i-1].s)id++;
a[wy[i].d]=id;
}
for(int i=1;i<=n;i++)ans+=(i-1)-getsum(a[i]),add(a[i],1);
printf("%d\n",ans);
fk();
for(int i=1;i<=belong[n];i++)ps(i);
scanf("%d",&t);
while(t--)
{
int x,y;
scanf("%d%d",&x,&y);
if(x>y)swap(x,y);
solve(x,y);
swap(a[x],a[y]);
if(belong[x]==belong[y])ps(belong[x]);
else ps(belong[x]),ps(belong[y]);
printf("%d\n",ans);
}
return 0;
}