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 }