程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ3067 樹狀數組+逆序數

POJ3067 樹狀數組+逆序數

編輯:C++入門知識

設兩線段為(x1,y1) ,(x2,y2), 若使兩線段相交,需使x1<x2&&y1>y2||x1>x2&&y1<y2.

那麼本題就變得很簡單了,對東邊點x從小到大排序,當x相等時對西邊點y從小到大排序,每插入一條線段,就求一下逆序對數。總和即為答案。

代碼如下:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #define MAXH 1005
 5 using namespace std;
 6 
 7 int n, m, k;
 8 struct mem{
 9     int x,y;              
10 }a[MAXH*MAXH];
11 
12 int c[1005];
13 bool cmp(mem a,mem b)                            
14 {
15     if(a.x==b.x) return a.y<b.y;
16     return a.x<b.x;
17 }
18 
19 int lowbit(int x)
20 {
21     return x&(-x);
22 }
23 
24 void add(int x)
25 {
26     while(x<=m)
27     {
28         c[x]++;
29         x+=lowbit(x);
30     }
31 }
32 
33 int sum(int x)
34 {
35     int mm=0;
36     while(x>0)
37     {
38         mm+=c[x];
39         x-=lowbit(x);
40     }
41     return mm;
42 }
43 
44 main()
45 {
46     int i, j, kk=1;
47     __int64 ans;
48     int t;
49     scanf("%d",&t);
50     while(t--)
51     {
52         memset(c,0,sizeof(c));
53         scanf("%d %d %d",&n,&m,&k);
54         for(i=0;i<k;i++)
55         scanf("%d %d",&a[i].x,&a[i].y);
56         sort(a,a+k,cmp);
57         ans=0;
58         for(i=0;i<k;i++)
59         {
60             ans+=sum(m)-sum(a[i].y);
61             add(a[i].y);
62         }
63         printf("Test case %d: %I64d\n",kk++,ans);
64     }
65 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved