POJ 3067 Japan(树状数组求逆序数)

Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built for the venue. Japan is tall island with N cities on the East coast and M cities on the West coast (M <= 1000, N <= 1000). K superhighways will be build. Cities on each coast are numbered 1, 2, ... from North to South. Each superhighway is straight line and connects city on the East coast with city of the West coast. The funding for the construction is guaranteed by ACM. A major portion of the sum is determined by the number of crossings between superhighways. At most two superhighways cross at one location. Write a program that calculates the number of the crossings between superhighways. 

Input
The input file starts with T - the number of test cases. Each test case starts with three numbers – N, M, K. Each of the next K lines contains two numbers – the numbers of cities connected by the superhighway. The first one is the number of the city on the East coast and second one is the number of the city of the West coast.
Output
For each test case write one line on the standard output:
Test case (case number): (number of crossings)
Sample Input

1
3 4 4
1 4
2 3
3 2
3 1

Sample Output

Test case 1: 5

日本有N个城市在东边,从北至南编号为1 2 3,,,N,M个城市在西边,从北至南编号为1 2 ,,,,M,K条高速公路将被建造

高速公路的一端在西边,一端在东边

输入有多组样例,

每组样例第一行为

n m k

接下来有k行,分别为高速公路的端点

求高速公路的交点有多少个,不包括以城市为相交点

解决方法:

对Ax,Ay和Bx,By两条高速公路,有相交点必须(Ax-Bx)*(Ay-By)<0

此方法是看网上大佬的。。。感激一个~~

#include<cstdio>
#include<cstring>
#include<iostream>
#include <algorithm>
#include<string>
using namespace std;

#define M 1003
#define LL long long
const int Max = 0x3f3f3f3f;
int c[M];
int n, m, k;

struct pp{
    int l;
    int r;
}p[M*M];

bool cmp(pp a, pp b){
    if(a.l == b.l) return a.r <= b.r;
    else return a.l < b.l;
}

int lowbit(int x){  //最后一个1的位置代表的数值
    return x &(-x);
}

void update(int x, int num){
    while(x <= m){
        c[x] += num;
        x += lowbit(x);
    }
}

LL getsum(int x){
    LL s = 0;
    while(x > 0){
        s += c[x];
        x -= lowbit(x);
    }
    return s;
}

int main(){
    int T, i, t = 0;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d%d", &n, &m, &k);
        for(i = 0; i < k; i++){
            scanf("%d%d", &p[i].l, &p[i].r);
        }
        sort(p, p + k, cmp);
        memset(c, 0, sizeof(c));
        LL s = 0;
        for(i = 0; i < k; i++){
            update(p[i].r, 1);
            s += (i + 1 - getsum(p[i].r));
        }
        t++;
        printf("Test case %d: %lld\n", t, s);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ling_wang/article/details/79357195