poj3067 Japan 树状数组 逆序数

题目链接:

http://poj.org/problem?id=3067

题意:

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

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

输入有多组样例,

每组样例第一行为

n m k

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

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

题解:

对Ax,Ay和Bx,By两条高速公路,有相交点必须(Ax-Bx)*(Ay-By)<0
所以就按照左边从大到小排序,找右边的逆序数。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 typedef long long ll;
 7 #define MS(a) memset(a,0,sizeof(a))
 8 #define MP make_pair
 9 #define PB push_back
10 const int INF = 0x3f3f3f3f;
11 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
12 inline ll read(){
13     ll x=0,f=1;char ch=getchar();
14     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
15     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
16     return x*f;
17 }
18 //////////////////////////////////////////////////////////////////////////
19 const int maxn = 1e6+10;
20 
21 ll bit[maxn];
22 
23 struct node{
24     int s,e;
25     bool operator<(const node& rhs) const{
26         if(s == rhs.s) return e < rhs.e;
27         return s < rhs.s;
28     }
29 }a[maxn];
30 
31 void add(int x,int v){
32     while(x<maxn){
33         bit[x] += v;
34         x += x&-x;
35     }
36 }
37 
38 ll sum(int x){
39     ll res = 0;
40     while(x > 0){
41         res += bit[x];
42         x -= x&-x;
43     }
44     return res;
45 }
46 
47 int main(){
48     int T = read();
49     for(int cas=1; cas<=T; cas++){
50         MS(bit);
51         int n,m,k; cin>>n>>m>>k;
52         for(int i=0; i<k; i++){
53             a[i].s=read(),a[i].e=read();
54         }
55         sort(a,a+k);
56 
57         ll ans = 0;
58         for(ll i=0; i<k; i++){
59             ans += i-sum(a[i].e);
60             add(a[i].e,1);
61         }
62 
63         cout << "Test case " << cas << ": " << ans << endl;
64     }
65 
66     return 0;
67 }
原文地址:https://www.cnblogs.com/yxg123123/p/6827568.html