题目大意
左边有n个点,从上到下依次为1、2、3、......、n-1、n
右边有m个点,从上到下一次为1、2、3、.......、m-1、m
然后有k条路,分别连接左右两边的点。
求这些路之间的交点有多少。每个交点至多被两条路径经过。
这一题的做法:
这一题其实就是求逆序对的稍微变化。只要将k个路径按照:x大的大,若x相等则y大的大。
代码:
bool operator < (const road &a, const road &b)
{
if (a.x == b.x)
return a.y > b.y;
else return a.x > b.x;
}
然后从大到小求a[i].y的逆序对即可
代码:
for (i=1; i<=k; i++)
{
ans += 1ll * query(a[i].y - 1);
updata(a[i].y, 1);
}
全部代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string>
#include <string.h>
using namespace std;
const int MAXN = 1000+100;
class road
{
public:
int x, y;
};
bool operator < (const road &a, const road &b)
{
if (a.x == b.x)
return a.y > b.y;
else return a.x > b.x;
}
int h[MAXN];
road a[MAXN*MAXN];
long long ans;
int n, m, k;
int lowbit(int x)
{
return x & (-x);
}
int query(int x)
{
int ans = 0;
while (x > 0)
{
ans += h[x];
x -= lowbit(x);
}
return ans;
}
void updata(int x, int val)
{
while (x <= m)
{
h[x] += val;
x += lowbit(x);
}
}
int main()
{
int T, i, x, y, tt = 0;
scanf("%d",&T);
while (T--)
{
ans = 0;
tt ++;
scanf("%d%d%d",&n,&m,&k);
for (i=1; i<=k; i++)
{
scanf("%d%d",&x,&y);
a[i].x = x;
a[i].y = y;
}
sort(a+1, a+k+1);
memset(h, 0, sizeof(h));
for (i=1; i<=k; i++)
{
ans += 1ll * query(a[i].y - 1);
updata(a[i].y, 1);
}
printf("Test case %d: %lld\n", tt, ans);
}
return 0;
}