分别开两个数组(c,d),(c[i])表示在(a)数组中第(i)大的数所在的位置(如果出现相同的数按照下标排序)
比如下面这个例子,理解一下
c | 1 | 4 | 5 | 2 | 3 |
---|---|---|---|---|---|
a | 1 | 3 | 5 | 1 | 2 |
(d[i])同理表示(b)数组
这实际是一种离散化,不过我们常用的离散化(c[i])表示(i)的排名,这个离散化(c[i])表示排名为(i)所在的下标
然后令(p[c[i]]=d[i]),表示他们之间的对应关系
比如下面这样
c | 1 | 4 | 5 | 2 | 3 |
---|---|---|---|---|---|
d | 3 | 2 | 1 | 5 | 4 |
p | 3 | 5 | 4 | 2 | 1 |
最终要求在各自数组中排名相同的在同一位置,即(p[i]=i)
所以要把(p)数组变成一个升序数列,假如(p[5]=3,p[3]=5)表示表示排名为(i)的元素在(a)中是第(5)个,在(b)中是第(3)个,排名为(j)的元素在(a)中是第(3)个,在(b)中是第(5)个
结论:使(p)数组由无序变为升序(每次只能交换相邻两个数),最小操作个数是逆序对数量之和。
因此对(p)数组求逆序对之和就行
(Code)
#include<cstdio>
#include<iostream>
#include<algorithm>
#define re register
#define maxn 101010
#define ll long long
#define mod 99999997
#define ls p<<1
#define rs p<<1|1
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll ans;
int len1,len2;
ll sums[maxn<<2];
int a[maxn],b[maxn],p[maxn],n;
struct PCC{
int id,num;
}c[maxn],d[maxn];
bool cmp(PCC A,PCC B)
{
if(A.num!=B.num)
return A.num<B.num;
return A.id<B.id;
}
void DCZ1()
{
sort(c+1,c+n+1,cmp);
for(re int i=1;i<=n;++i)
a[i]=c[i].id;
}
void DCZ2()
{
sort(d+1,d+n+1,cmp);
for(re int i=1;i<=n;++i)
b[i]=d[i].id;
}
void push_up(int p)
{
sums[p]=sums[ls]+sums[rs];
}
void insert(int p,int l,int r,int k)
{
if(l==r)
{
sums[p]++;
return ;
}
int mid=(l+r)>>1;
if(k<=mid) insert(ls,l,mid,k);
else insert(rs,mid+1,r,k);
push_up(p);
}
int query(int p,int l,int r,int k)
{
int tmp=0;
if(l==r)
{
if(l<=k) tmp+=sums[p];
return tmp;
}
int mid=(l+r)>>1;
if(k>mid) tmp+=sums[ls],tmp+=query(rs,mid+1,r,k);
else tmp+=query(ls,l,mid,k);
return tmp;
}
void solve()
{
for(re int i=1;i<=n;++i)
{
ll tmp=(i-1)-query(1,1,n,p[i]);
tmp=(tmp%mod+mod)%mod;
ans=(ans+tmp)%mod;
insert(1,1,n,p[i]);
}
}
int main()
{
n=read();
for(re int i=1;i<=n;++i) a[i]=read(),c[i].num=a[i],c[i].id=i;
for(re int i=1;i<=n;++i) b[i]=read(),d[i].num=b[i],d[i].id=i;
DCZ1(),DCZ2();
for(re int i=1;i<=n;++i)
p[a[i]]=b[i];
solve();
printf("%lld
",ans);
return 0;
}