标签:
1 /*
2 题意:给了两行的数字,相同的数字连线,问中间交点的个数
3 逆序数:第一行保存每个数字的位置,第二行保存该数字在第一行的位置,接下来就是对它求逆序数
4 用归并排序或线段树求。想到了就简单了:)
5 */
6 #include <cstdio>
7 #include <algorithm>
8 #include <cstring>
9 #include <cmath>
10 #include <vector>
11 using namespace std;
12
13 typedef long long ll;
14 const int MAXN = 1e5 + 10;
15 const int INF = 0x3f3f3f3f;
16 int p[MAXN], a[MAXN];
17 int L[MAXN/2+10], R[MAXN/2+10];
18 ll ans;
19
20 void Merge(int *a, int p, int q, int r)
21 {
22 int n1 = q - p + 1, n2 = r - q;
23 for (int i=1; i<=n1; ++i) L[i] = a[p+i-1];
24 for (int i=1; i<=n2; ++i) R[i] = a[q+i];
25 L[n1+1] = INF; R[n2+1] = INF;
26
27 int i = 1, j = 1;
28 for (int k=p; k<=r; ++k)
29 {
30 if (L[i] <= R[j]) a[k] = L[i++];
31 else {a[k] = R[j++]; ans += n1 - i + 1;}
32 }
33 }
34
35 void MergeSort(int *a, int p, int r)
36 {
37 if (p < r)
38 {
39 int q = (p + r) / 2;
40 MergeSort (a, p, q);
41 MergeSort (a, q + 1, r);
42 Merge (a, p, q, r);
43 }
44 }
45
46 int main(void) //UVALive 6508 Permutation Graphs
47 {
48 // freopen ("I.in", "r", stdin);
49
50 int t; scanf ("%d", &t);
51 while (t--)
52 {
53 int n; scanf ("%d", &n);
54 for (int i=1; i<=n; ++i)
55 {
56 int x; scanf ("%d", &x); p[x] = i;
57 }
58 for (int i=1; i<=n; ++i)
59 {
60 int x; scanf ("%d", &x); a[i] = p[x];
61 }
62
63 ans = 0;
64 MergeSort (a, 1, n);
65 printf ("%lld\n", ans);
66 }
67
68 return 0;
69 }
逆序数 UVALive 6508 Permutation Graphs
标签:
原文地址:http://www.cnblogs.com/Running-Time/p/4597813.html