POJ 2299 Ultra-QuickSort(樹狀數組+離散化)
阿新 • • 發佈:2017-05-07
計算 htm upd ace stream max arc clas 下標
http://poj.org/problem?id=2299
題意:
給出一組數,求逆序對。
思路:
這道題可以用樹狀數組解決,但是在此之前,需要對數據進行一下預處理。
這道題目的數據可以大到999,999,999,但數組肯定是無法開這麽大的,但是每組數據最多只有500000個,那麽,怎麽辦呢,離散化!
離散化,也就是將數據和1~n做一一映射。
比如:
9 1 0 5 4
離散化之後變成
5 2 1 4 3
這樣的話,就可以放心的開數組啦!
至於樹狀數組的計算過程,我懶得寫了,直接摘抄一下大神的http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html
在離散結果中間結果的基礎上,那麽其計算逆序數的過程是這麽一個過程。 1,輸入5, 調用upDate(5, 1),把第5位設置為1 1 2 3 4 5 0 0 0 0 1 計算1-5上比5小的數字存在麽? 這裏用到了樹狀數組的getSum(5) = 1操作, 現在用輸入的下標1 - getSum(5) = 0 就可以得到對於5的逆序數為0。 2. 輸入2, 調用upDate(2, 1),把第2位設置為1 1 2 3 4 5 0 1 0 0 1 計算1-2上比2小的數字存在麽? 這裏用到了樹狀數組的getSum(2) = 1操作, 現在用輸入的下標2- getSum(2) = 1 就可以得到對於2的逆序數為1。 3. 輸入1, 調用upDate(1, 1),把第1位設置為1 1 2 3 4 5 1 1 0 0 1 計算1-1上比1小的數字存在麽? 這裏用到了樹狀數組的getSum(1) = 1操作, 現在用輸入的下標 3 - getSum(1) = 2 就可以得到對於1的逆序數為2。 4. 輸入4, 調用upDate(4, 1),把第5位設置為1 1 2 3 4 5 1 1 0 1 1 計算1-4上比4小的數字存在麽? 這裏用到了樹狀數組的getSum(4) = 3操作, 現在用輸入的下標4- getSum(4) = 1 就可以得到對於4的逆序數為1。 5. 輸入3, 調用upDate(3, 1),把第3位設置為1 1 2 3 4 5 1 1 1 1 1 計算1-3上比3小的數字存在麽? 這裏用到了樹狀數組的getSum(3) = 3操作, 現在用輸入的下標5 - getSum(3) = 2 就可以得到對於3的逆序數為2。 6. 0+1+2+1+2 = 6 這就是最後的逆序數
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<queue> 7 #include<cmath> 8 #include<map> 9 #include<stack> 10 using namespace std; 11 12 const int maxn=500000+5; 13 14 int n; 15 16 struct node 17 { 18 int val; 19 int pos; 20 }a[maxn]; 21 22 int b[maxn]; 23 int c[maxn]; 24 25 bool cmp(node a,node b) 26 { 27 return a.val<b.val; 28 } 29 30 int lowbit(int x) 31 { 32 return x&-x; 33 } 34 35 int sum(int x) 36 { 37 int ret=0; 38 while(x>0) 39 { 40 ret+=c[x]; 41 x-=lowbit(x); 42 } 43 return ret; 44 } 45 46 void add(int x,int d) 47 { 48 while(x<=n) 49 { 50 c[x]+=d; 51 x+=lowbit(x); 52 } 53 } 54 55 int main() 56 { 57 //freopen("D:\\input.txt","r",stdin); 58 while(~scanf("%d",&n) && n) 59 { 60 for(int i=1;i<=n;i++) 61 { 62 scanf("%d",&a[i].val); 63 a[i].pos=i; 64 } 65 sort(a+1,a+1+n,cmp); 66 for(int i=1;i<=n;i++) 67 b[a[i].pos]=i; 68 memset(c,0,sizeof(c)); 69 long long ans=0; 70 for(int i=1;i<=n;i++) 71 { 72 add(b[i],1); 73 ans+=i-sum(b[i]); 74 } 75 printf("%lld\n",ans); 76 } 77 return 0; 78 }
POJ 2299 Ultra-QuickSort(樹狀數組+離散化)