分块,每个块内套一个树状数组。
qwq开始数组开小了RE。。。
整块的树状数组维护,块外的暴力统计就好了。
看到hzwer写了个一维的很厉害的样子qwq没仔细看150+行啊。。
膜ws_yzy树套树随便虐此题qwq,虽然跑了我两倍的时间qwq。。。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define lowbit(i) (i&(-i))
using namespace std;
int n,m,cnt,block,block_sum,ans;
int h[20005],num[20005],hash[20005],belong[20005],tree[200][20005];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline int find(int x)
{
int l=1,r=cnt;
while (l<=r)
{
int mid=l+r>>1;
if (hash[mid]==x) return mid;
else if (hash[mid]<x) l=mid+1;
else r=mid-1;
}
}
inline void add(int block_id,int x,int val)
{
for (int i=x;i<=cnt;i+=lowbit(i)) tree[block_id][i]+=val;
}
inline int query(int block_id,int x)
{
int tmp=0;
for (int i=x;i;i-=lowbit(i)) tmp+=tree[block_id][i];
return tmp;
}
inline int work(int j,int ls,int rs)
{
int x=find(h[j]);
int tmp=0;
if (x<ls) tmp-=1;
if (x>ls) tmp+=1;
if (x<rs) tmp+=1;
if (x>rs) tmp-=1;
return tmp;
}
int main()
{
n=read();
for (int i=1;i<=n;i++) h[i]=num[i]=read();
sort(num+1,num+n+1);
hash[++cnt]=num[1];
for (int i=2;i<=n;i++)
if (num[i]!=num[i-1]) hash[++cnt]=num[i];
block=(int)(sqrt(n));
if (n%block) block_sum=n/block+1; else block_sum=n/block;
for (int i=1;i<=n;i++) belong[i]=(i-1)/block+1;
for (int i=n;i;i--)
{
int x=find(h[i]);
ans+=query(0,x-1);
add(0,x,1);
}
for (int i=1;i<=block_sum;i++)
{
int l=(i-1)*block+1,r=min(n,i*block);
for (int j=r;j>=l;j--)
{
int x=find(h[j]);
add(i,x,1);
}
}
printf("%d\n",ans);
m=read();
for (int i=1;i<=m;i++)
{
int l=read(),r=read();
if (l>r) swap(l,r);
int ls=find(h[l]),rs=find(h[r]);
int x=belong[l],y=belong[r];
if (x!=y)
{
for (int j=x+1;j<y;j++)
ans+=query(j,rs-1)-query(j,cnt)+query(j,rs)-query(j,ls-1)+query(j,cnt)-query(j,ls);
add(x,ls,-1); add(x,rs,1); add(y,rs,-1); add(y,ls,1);
int l_r=x*block,r_l=(y-1)*block+1;
for (int j=l+1;j<=l_r;j++) ans+=work(j,ls,rs);
for (int j=r_l;j<r;j++) ans+=work(j,ls,rs);
}
else for (int j=l+1;j<r;j++) ans+=work(j,ls,rs);
if (h[l]<h[r]) ans++;
else if (h[l]>h[r]) ans--;
swap(h[l],h[r]);
printf("%d\n",ans);
}
return 0;
}