# 火柴排队 详解

4
2 3 1 4
3 2 1 4

1

4
1 3 4 2
1 7 2 4

2

## 分析

#### 同序操作

struct node {
LL val, num;
};


###### 离散化

bool cmp(node x, node y) {
if(x.val == y.val)
return x.num < y.num;
return x.val < y.val;
}

for(LL i = 1;i <= n; i++) {
scanf("%lld", &a[i].val);
a[i].num = i;
}
for(LL i = 1;i <= n; i++) {
scanf("%lld", &b[i].val);
b[i].num = i;
}
sort(a + 1, a + 1 + n, cmp);
sort(b + 1, b + 1 + n, cmp);


A : ( 1 , 3 , 4 , 2 ) 和 B : ( 1 , 4 , 2 , 3 ) A:(1,3,4,2)和B:(1,4,2,3)

##### 逆序对

• 1.暴力枚举 O ( n 2 ) O(n^2)
只能得到80pts。
 for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
if (x[i] > x[j]) {
ans++;
ans %= MOD;
}

• 2.归并排序 O ( l o g n ) O(logn)
void merge(LL L, LL R, LL Mid){
LL i = L;LL j = Mid + 1;LL k = L;
while(i <= Mid && j <= R){
if(x[i] <= x[j])t[k ++] = x[i ++];
else{
ans += Mid - i + 1;
ans %= MOD;
t[k ++] = x[j ++];
}
}
while(i <= Mid)t[k ++] = x[i ++];
while(j <= R)t[k ++] = x[j ++];
for(i = L; i <= R; i ++)x[i] = t[i];
}
void mergesort(LL L, LL R){
if(L < R){
LL Mid = (L + R) / 2;
mergesort(L, Mid),mergesort(Mid + 1, R);
merge(L, R, Mid);
}
}

• 3.树状数组
我太菜了。。。还没学会。。。

### 参考代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#define LL long long
using namespace std;
const int MAXN = 100005;
const int MOD = 99999997;

struct node {
LL val, num;
};

LL n, ans, x[MAXN], t[MAXN];
node a[MAXN], b[MAXN];

bool cmp(node x, node y) {
if(x.val == y.val)
return x.num < y.num;
return x.val < y.val;
}

void merge(LL L, LL R, LL Mid){
LL i = L;LL j = Mid + 1;LL k = L;
while(i <= Mid && j <= R){
if(x[i] <= x[j])t[k ++] = x[i ++];
else{
ans += Mid - i + 1;
ans %= MOD;
t[k ++] = x[j ++];
}
}
while(i <= Mid)t[k ++] = x[i ++];
while(j <= R)t[k ++] = x[j ++];
for(i = L; i <= R; i ++)x[i] = t[i];
}
void mergesort(LL L, LL R){
if(L < R){
LL Mid = (L + R) / 2;
mergesort(L, Mid),mergesort(Mid + 1, R);
merge(L, R, Mid);
}
}

int main() {
scanf("%lld", &n);
for(LL i = 1;i <= n; i++) {
scanf("%lld", &a[i].val);
a[i].num = i;
}
for(LL i = 1;i <= n; i++) {
scanf("%lld", &b[i].val);
b[i].num = i;
}
sort(a + 1, a + 1 + n, cmp);
sort(b + 1, b + 1 + n, cmp);
for(LL i = 1;i <= n; i++) {
x[a[i].num] = b[i].num;
}
mergesort(1, n);
printf("%lld\n", ans % MOD);
return 0;
}


10-02 18

09-13 23
10-30 1185
07-08 64
08-22 16
10-18 4万+
11-07 3806
05-10 1016
07-02 268
02-03 179
03-01 14万+
10-12 669
08-30 4440
11-13 354
10-26 396