Description
排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。
【数据规模和约定】
对于100%的数据,1≤m≤2*103,1≤n≤2*104,1≤hi≤109,ai≠bi,1≤ai,bi≤n。
Input
第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi¬,表示交换位置ai与位置bi的小朋友。
Output
输出文件共m行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。
归并排序求初始状态逆序对数,线段树套平衡树维护每个区间的数,
修改时删去修改位置的数重新添加,计算删去/添加一个数后减少/增加的逆序对数
#include<cstdio> #include<cstdlib> #define N 2000000 int ch[N][2]; int sz[N],a[N]; int v[N]; int p=1,V; inline void upd(int x){ if(x)sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; } struct bst{ int root; bst(){ root=0; } void insert(int x){ v[p]=V=x; sz[p]=1; a[p]=rand(); if(root)_insert(root); else root=p++; } void _insert(int&x){ bool d=V>v[x]; int&c=ch[x][d]; if(c)_insert(c); else c=p++; if(a[ch[x][d]]>a[x])rot(x,d); upd(x); } void rot(int&w,int c){ int u=ch[w][c]; ch[w][c]=ch[u][c^1]; ch[u][c^1]=w; upd(w); w=u; upd(u); } int lss(int x){ int w=root,ans=0; while(w){ if(v[w]<x)ans+=sz[ch[w][0]]+1; w=ch[w][v[w]<x]; } return ans; } int mre(int x){ int w=root,ans=0; while(w){ if(v[w]>x)ans+=sz[ch[w][1]]+1; w=ch[w][v[w]<=x]; } return ans; } void del(int&w,int V){ if(!w)return; if(v[w]==V)del(w); else del(ch[w][v[w]<V],V); upd(w); } void del(int&w){ if(ch[w][0]|ch[w][1]){ bool d=a[ch[w][0]]<a[ch[w][1]]; int u=ch[w][d]; rot(w,d); del(ch[w][d^1]); upd(u); }else w=0; } }; bst tr[65536]; void tr_ins(int i,int x){ for(i+=32768;i>1;i>>=1)tr[i].insert(x); } void tr_del(int i,int x){ for(i+=32768;i>1;i>>=1)tr[i].del(tr[i].root,x); } int tr_get(int i,int x){ int ans=0; for(i+=32768;i>1;i>>=1){ if(i&1)ans+=tr[i^1].mre(x); else ans+=tr[i^1].lss(x); } return ans; } int n,m,ans=0; int p1,p2; int h[20005],h2[20005],h3[20005]; void msort(int l,int r){ int m=l+r>>1; if(l<m)msort(l,m); if(m+1<r)msort(m+1,r); int p1=l,p2=m+1,p3=l; while(p1<=m&&p2<=r){ if(h2[p1]>h2[p2])h3[p3++]=h2[p2++],ans+=m+1-p1; else h3[p3++]=h2[p1++]; } while(p1<=m)h3[p3++]=h2[p1++]; while(p2<=r)h3[p3++]=h2[p2++]; for(int i=l;i<=r;i++)h2[i]=h3[i]; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",h+i); h2[i]=h[i]; tr_ins(i,h[i]); } msort(1,n); printf("%d ",ans); scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%d%d",&p1,&p2); int v1=h[p1],v2=h[p2]; ans-=tr_get(p1,v1); ans-=tr_get(p2,v2); if(p1<p2&&v1>v2||p1>p2&&v1<v2)ans++; tr_del(p1,v1); tr_ins(p1,v2); h[p1]=v2; tr_del(p2,v2); tr_ins(p2,v1); ans+=tr_get(p2,v1); ans+=tr_get(p1,v2); if(p1<p2&&v1<v2||p1>p2&&v1>v2)ans--; h[p2]=v1; printf("%d ",ans); } return 0; }