火柴排队
贪心地考虑将两个序列排序后对应应该最优
将一个序列中在另一个序列中对应位置维护
最后求逆序对个数
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(),x.end()
#define U(i,u) for(register int i=head[u];i;i=nxt[i])
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
#define per(i,a,b) for(register int i=(a);i>=(b);--i)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> PII;
typedef vector<int> VI;
template<class T> inline void read(T &x){
x=0;char c=getchar();int f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f;
}
template<class T> inline void cmin(T &x, T y){x=x<y?x:y;}
template<class T> inline void cmax(T &x, T y){x=x>y?x:y;}
const int N=100001;
const int P=99999997;
int n,to[N],ans;
struct node{
int x,id;
}a[N],b[N];
bool cmp(node aa,node bb){
return aa.x<bb.x;
}
int c[N];
int lowbit(int x){return x&(-x);}
void add(int x,int dt){
while(x<=n){
c[x]=(c[x]+dt)%P;
x+=lowbit(x);
}
}
int sum(int x){
int ret=0;while(x){
ret=(ret+c[x])%P;
x-=lowbit(x);
}return ret;
}
int main(){
read(n);rep(i,1,n)read(a[i].x),a[i].id=i;rep(i,1,n)read(b[i].x),b[i].id=i;
sort(a+1,a+n+1,cmp);sort(b+1,b+n+1,cmp);
rep(i,1,n){
to[a[i].id]=b[i].id;
}
rep(i,1,n){
ans=(ans+sum(n)-sum(to[i]))%P;
add(to[i],1);
}
printf("%d",ans);
return 0;
}