Description
Input
Output
Sample Input
1 3 4 4 1 4 2 3 3 2 3 1
Sample Output
Test case 1: 5
这题每个点可以发出多条边,只需按照每条边的端点大小排序,先按照左边从大到小,然后右边从大到小。 这样处理之后,左边的端点依次标记为1 ~ num。不会对结果造成影响。然后就是赤裸裸的逆序对的问题了。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <stack>
#include <cctype>
#include <algorithm>
#define lson o<<1, l, m
#define rson o<<1|1, m+1, r
using namespace std;
typedef long long LL;
const int mod = 99999997;
const int MAX = 1000000000;
const int maxn = 100005;
int t, n, m, k, f[1000005];
struct C {
int st, en;
} in[1000005];
LL c[1000005];
bool cmp(C x, C y) {
if(x.st != y.st) return x.st < y.st;
return x.en < y.en;
}
int main()
{
// freopen("in.txt", "r", stdin);
cin >> t;
for(int ca = 1; ca <= t; ca++) {
cin >> n >> m >> k;
for(int i = 0; i < k; i++) scanf("%d%d", &in[i].st, &in[i].en);
sort(in, in+k, cmp);
int num = 0;
for(int i = 0; i < k; i++) {
num++;
in[i].st = num;
f[num] = in[i].en;
}
memset(c, 0, sizeof(c));
LL sum = 0;
for(int i = 1; i <= num; i++) {
for(int j = f[i]+1; j <= maxn; j += j&-j) sum += c[j];
for(int j = f[i]; j > 0; j -= j&-j) c[j]++;
}
printf("Test case %d: %I64d\n", ca, sum);
}
return 0;
}
原文:http://blog.csdn.net/u013923947/article/details/38803925