您的位置:首页 > 其它

逆序数 UVALive 6508 Permutation Graphs

2015-06-24 15:24 323 查看
题目传送门

 /*
题意:给了两行的数字,相同的数字连线,问中间交点的个数
逆序数:第一行保存每个数字的位置,第二行保存该数字在第一行的位置,接下来就是对它求逆序数
用归并排序或线段树求。想到了就简单了:)
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;

typedef long long ll;
const int MAXN = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int p[MAXN], a[MAXN];
int L[MAXN/2+10], R[MAXN/2+10];
ll ans;

void Merge(int *a, int p, int q, int r)
{
int n1 = q - p + 1, n2 = r - q;
for (int i=1; i<=n1; ++i)    L[i] = a[p+i-1];
for (int i=1; i<=n2; ++i)    R[i] = a[q+i];
L[n1+1] = INF;    R[n2+1] = INF;

int i = 1, j = 1;
for (int k=p; k<=r; ++k)
{
if (L[i] <= R[j])    a[k] = L[i++];
else    {a[k] = R[j++];    ans += n1 - i + 1;}
}
}

void MergeSort(int *a, int p, int r)
{
if (p < r)
{
int q = (p + r) / 2;
MergeSort (a, p, q);
MergeSort (a, q + 1, r);
Merge (a, p, q, r);
}
}

int main(void)        //UVALive 6508 Permutation Graphs
{
//    freopen ("I.in", "r", stdin);

int t;    scanf ("%d", &t);
while (t--)
{
int n;    scanf ("%d", &n);
for (int i=1; i<=n; ++i)
{
int x;    scanf ("%d", &x);    p[x] = i;
}
for (int i=1; i<=n; ++i)
{
int x;    scanf ("%d", &x);    a[i] = p[x];
}

ans = 0;
MergeSort (a, 1, n);
printf ("%lld\n", ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: