看不出是逆序对...感觉药丸
首先要看出最优解就是两个数组均有序的时候
再对两个数组的下标求逆序对即可
归并&树状数组
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<ctype.h> 6 #define MODD 99999997 7 using namespace std; 8 const int maxn=100100; 9 int n,ans; 10 int a[maxn],b[maxn]; 11 int data[maxn]; 12 struct node{ 13 int num,pos; 14 }store[maxn]; 15 int read(){ 16 int x=0,f=1; 17 char ch=getchar(); 18 while (!isdigit(ch)){ 19 if (ch=='-') f=-1; 20 ch=getchar(); 21 } 22 while (isdigit(ch)){ 23 x=x*10+ch-'0'; 24 ch=getchar(); 25 } 26 return x*f; 27 } 28 bool cmp(node a,node b){ 29 return a.num<b.num; 30 } 31 void init(){ 32 for (int i=1;i<=n;i++){ 33 store[i].num=read();store[i].pos=i; 34 } 35 sort(store+1,store+n+1,cmp); 36 for (int i=1;i<=n;i++) a[i]=store[i].pos; 37 38 for (int i=1;i<=n;i++){ 39 store[i].num=read();store[i].pos=i; 40 } 41 sort(store+1,store+n+1,cmp); 42 for (int i=1;i<=n;i++) b[store[i].pos]=a[i]; 43 } 44 void merge(int l,int r){ 45 if (l>=r) return; 46 int mid=(l+r)>>1; 47 merge(l,mid); 48 merge(mid+1,r); 49 int p1=l,p2=mid+1; 50 int tot=l; 51 while (p1<=mid&&p2<=r){ 52 if (b[p1]<b[p2]) data[tot++]=b[p1++]; 53 else { 54 ans+=mid-p1+1;ans%=MODD; 55 data[tot++]=b[p2++]; 56 } 57 } 58 while (p1<=mid) data[tot++]=b[p1++]; 59 while (p2<=r) data[tot++]=b[p2++]; 60 for (int i=l;i<=r;i++) b[i]=data[i]; 61 } 62 int main(){ 63 memset(a,0,sizeof(a)); 64 memset(b,0,sizeof(b)); 65 n=read(); 66 init(); 67 ans=0; 68 merge(1,n); 69 printf("%d\n",ans); 70 return 0; 71 }