题目链接:http://poj.org/problem?id=3067
题目大意:输入K组数据,每组包含两个整数,分别代表东西海岸的城市的编号,表示连接对应编号的城市形成的路线,输出这K条路线的交点数,每个交点只由2条路线交叉而成;
思路:将线路数据存入结构体数组line中,将其按x升序排列,若x相同,则按y升序;利用sum函数统计当前线路左边(左边指排序后小于当前元素的一方)y值小于它的元素个数,并在计数器ans中累加,注意ans需使用__int64,然后更新line的值;
代码实现:
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int c[1111];
struct Node
{
int x,y;
}line[1111111];
int N, M, K;
bool cmp(Node a, Node b)//按x升序,若x相同,按y升序
{
if(a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
int lowbit(int x)
{
return x & (-x);
}
void update(int i)
{
while(i <= M)
{
c[i] ++;
i += lowbit(i);
}
}
int sum(int i)//统计当前元素左边y值小于它的元素个数
{
int s = 0;
while(i > 0)
{
s += c[i];
i -= lowbit(i);
}
return s;
}
int main()
{
int i, j;
int T;
scanf("%d", &T);
for(i = 1; i <= T; i++)
{
scanf("%d %d %d", &N, &M, &K);
for(j = 1; j <= K; j++)
{
scanf("%d %d", &line[j].x, &line[j].y);
}
sort(line+1, line+1+K, cmp);
memset(c, 0, sizeof(c));
__int64 ans = 0; //数值太大
for(j = 1; j <= K; j++)
{
ans += sum(M) - sum(line[j].y);
update(line[j].y);
}
printf("Test case %d: %I64d\n", i, ans);
}
return 0;
}