题目:http://poj.org/problem?id=3067
题意:在东西两侧分别有n和m个城市,现在要在两侧城市间建k条公路,问这些公路的交叉点有多少个
思路:对给出的公路,按其中一侧排序,然后用树状数组求另一侧的逆序对数,所有逆序对数就是答案
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 1010;
int bit[N], n, m, k;
int cas;
struct node
{
int x, y;
} g[N*N];
bool cmp(node a, node b)
{
if(a.x != b.x) return a.x < b.x;
else return a.y < b.y;
}
void add(int i, int x)
{
while(i <= n)
bit[i] += x, i += i & -i;
}
int sum(int i)
{
int s = 0;
while(i > 0)
s += bit[i], i -= i & -i;
return s;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d", &m, &n, &k);
for(int i = 0; i < k; i++)
scanf("%d%d", &g[i].x, &g[i].y);
sort(g, g + k, cmp);
memset(bit, 0, sizeof bit);
ll res = 0;
for(int i = 0; i < k; i++)
{
add(g[i].y, 1);
res += i + 1 - sum(g[i].y); //因为我下标从0开始的,所以要i + 1再去减
}
printf("Test case %d: %lld\n", ++cas, res);
}
return 0;
}