分块大法吼
一开始没判有h相等的情况wa了好久qaq
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
typedef long long LL;
inline int read()
{
int x=0;bool f=0;char c=getchar();
for (;c<'0'||c>'9';c=getchar()) f=c=='-'?1:0;
for (;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
return f?-x:x;
}
const int N=20010,B=200;
int n,m,num[N],h[N],p[N],ln[N],bl[N],bn=0,ans=0;
struct na
{
int ss[N];
inline void add(int x,int a)
{
for (;x<=n;x+=x&-x) ss[x]+=a;
}
inline int cal(int x)
{
int rec=0;
for (;x;x-=x&-x) rec+=ss[x];
return rec;
}
}e[N/B+3],ee;
inline bool cmp (const int a,const int b)
{
return num[a]<num[b];
}
int main()
{
n=read();
for (int i=1;i<=n;i++) num[i]=read(),p[i]=i;
sort(p+1,p+n+1,cmp);h[p[1]]=1;
for (int i=1;i<=n;i++) h[p[i]]=h[p[i-1]]+(num[p[i]]>num[p[i-1]]?1:0);
for (int i=1;i<=n;i+=B) ln[++bn]=i;ln[bn+1]=n+1;
for (int i=1;i<=bn;i++)
for (int j=ln[i];j<ln[i+1];j++)
bl[j]=i,e[i].add(h[j],1);
for (int i=n;i;i--)
ans+=ee.cal(h[i]-1),ee.add(h[i],1);
printf("%d\n",ans);
m=read();
for (int u,v;m--;)
{
u=read();v=read();
if (u==v) {printf("%d\n",ans);continue;}
if (u>v) swap(u,v);
if (h[u]<h[v]) ans++;
if (h[u]>h[v]) ans--;
e[bl[u]].add(h[u],-1);e[bl[v]].add(h[u],1);
e[bl[v]].add(h[v],-1);e[bl[u]].add(h[v],1);
if (bl[u]==bl[v])
{
for (int i=u+1;i<v;i++)
{
if (h[u]<h[i]) ans++;
if (h[u]>h[i]) ans--;
if (h[i]<h[v]) ans++;
if (h[i]>h[v]) ans--;
}
printf("%d\n",ans);
swap(h[u],h[v]);
continue;
}
for (int i=u+1;i<ln[bl[u]+1];i++)
{
if (h[u]<h[i]) ans++;
if (h[u]>h[i]) ans--;
if (h[i]<h[v]) ans++;
if (h[i]>h[v]) ans--;
}
for (int i=ln[bl[v]];i<v;i++)
{
if (h[u]<h[i]) ans++;
if (h[u]>h[i]) ans--;
if (h[i]<h[v]) ans++;
if (h[i]>h[v]) ans--;
}
for (int i=bl[u]+1,r1,r2;i<bl[v];i++)
{
r1=e[i].cal(h[u]-1);r2=e[i].cal(n)-e[i].cal(h[u]);
ans-=r1;ans+=r2;
r1=e[i].cal(h[v]-1);r2=e[i].cal(n)-e[i].cal(h[v]);
ans-=r2;ans+=r1;
}
swap(h[u],h[v]);
printf("%d\n",ans);
}
return 0;
}