卧槽,为什么网上没有主席树的题解呀?!!!
貌似分块也可以做,但是代码会长一点吧,真心良心题不卡空间,O(nlog^2n)随便水。
结果发现自己忘考虑相同的数,一开始逆序对数求错了。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 8000100
using namespace std;
struct yts
{
int x,id;
}a[20010];
int lch[maxn],rch[maxn],cnt[maxn];
int root[20010],c[20010],f[20010],l[30],r[30];
int n,T,tot,mx,ans,llen,rlen;
int lowbit(int x)
{
return x&(-x);
}
bool cmp(yts a,yts b)
{
return a.x<b.x;
}
void add(int i,int x)
{
while (i<=n)
{
c[i]+=x;
i+=lowbit(i);
}
}
int query(int x)
{
int ans=0;
for (int i=x;i;i-=lowbit(i)) ans+=c[i];
return ans;
}
int modify(int pre,int l,int r,int x,int f)
{
int now=++tot;
if (l==r)
{
cnt[now]=cnt[pre]+f;lch[now]=rch[now]=0;
}
else
{
int mid=(l+r)/2;
if (x<=mid)
{
rch[now]=rch[pre];lch[now]=modify(lch[pre],l,mid,x,f);
}
else
{
lch[now]=lch[pre];rch[now]=modify(rch[pre],mid+1,r,x,f);
}
cnt[now]=cnt[lch[now]]+cnt[rch[now]];
}
return now;
}
void modify(int x,int t,int f)
{
for (int i=x;i<=n;i+=lowbit(i)) root[i]=modify(root[i],1,mx,t,f);
}
int askless(int L,int R,int x)
{
if (x<L) return 0;
if (R<=x)
{
int sum=0;
for (int i=1;i<=llen;i++) sum-=cnt[l[i]];
for (int i=1;i<=rlen;i++) sum+=cnt[r[i]];
return sum;
}
int mid=(L+R)/2;
if (x<=mid)
{
for (int i=1;i<=llen;i++) l[i]=lch[l[i]];
for (int i=1;i<=rlen;i++) r[i]=lch[r[i]];
return askless(L,mid,x);
}
else
{
int sum=0;
for (int i=1;i<=llen;i++) sum-=cnt[lch[l[i]]];
for (int i=1;i<=rlen;i++) sum+=cnt[lch[r[i]]];
for (int i=1;i<=llen;i++) l[i]=rch[l[i]];
for (int i=1;i<=rlen;i++) r[i]=rch[r[i]];
return sum+askless(mid+1,R,x);
}
}
int askmore(int L,int R,int x)
{
if (x>R) return 0;
if (x<=L)
{
int sum=0;
for (int i=1;i<=llen;i++) sum-=cnt[l[i]];
for (int i=1;i<=rlen;i++) sum+=cnt[r[i]];
return sum;
}
int mid=(L+R)/2;
if (mid<x)
{
for (int i=1;i<=llen;i++) l[i]=rch[l[i]];
for (int i=1;i<=rlen;i++) r[i]=rch[r[i]];
return askmore(mid+1,R,x);
}
else
{
int sum=0;
for (int i=1;i<=llen;i++) sum-=cnt[rch[l[i]]];
for (int i=1;i<=rlen;i++) sum+=cnt[rch[r[i]]];
for (int i=1;i<=llen;i++) l[i]=lch[l[i]];
for (int i=1;i<=rlen;i++) r[i]=lch[r[i]];
return sum+askmore(L,mid,x);
}
}
void mem(int x,int y)
{
llen=0,rlen=0;
for (int i=x;i;i-=lowbit(i)) l[++llen]=root[i];
for (int i=y;i;i-=lowbit(i)) r[++rlen]=root[i];
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i].x);
for (int i=1;i<=n;i++) a[i].id=i;
sort(a+1,a+n+1,cmp);
mx=1;f[a[1].id]=1;
for (int i=2;i<=n;i++)
{
if (a[i].x!=a[i-1].x) mx++;
f[a[i].id]=mx;
}
for (int i=n;i>=1;i--)
{
ans+=query(f[i]-1);
add(f[i],1);
}
printf("%d\n",ans);
tot=0;root[0]=cnt[0]=lch[0]=rch[0]=0;
for (int i=1;i<=n;i++) root[i]=root[0];
for (int i=1;i<=n;i++) modify(i,f[i],1);
scanf("%d",&T);
while (T--)
{
int x,y;
scanf("%d%d",&x,&y);
if (x>y) swap(x,y);
mem(x,y);
ans-=askless(1,mx,f[x]-1);
mem(x,y);
ans-=askmore(1,mx,f[y]+1);
mem(x,y);
ans+=askmore(1,mx,f[x]+1);
mem(x,y);
ans+=askless(1,mx,f[y]-1);
printf("%d\n",ans);
modify(x,f[x],-1);modify(x,f[y],1);
modify(y,f[y],-1);modify(y,f[x],1);
swap(f[x],f[y]);
}
return 0;
}