1. 程式人生 > 實用技巧 >【KickStart】Round H 2019: H-index

【KickStart】Round H 2019: H-index

起因:本來說好打遊戲的人咕咕咕了

題目連結:https://codingcompetitions.withgoogle.com/kickstart/round/0000000000050edd/00000000001a274e

一直想多刷題來著,但是總犯懶。今天也只刷了這一道,典型的樹狀陣列題(之前還不太會,現學現用吧……)。簡單分析,題目數值範圍比較大,需要快速求解大於等於H的數值有多少個,數值有大小範圍,可以用一個計數陣列存下來,然後樹狀陣列求區間值就可以了。

樹狀陣列簡單理解,就是重用區間和。計算當前下標的二進位制,有N個0,就往前(包括自己)數2^N個數加和。通過x & (-x)的方式消除二進位制最後一個1,然後在新的下標下繼續求和。

 1 #include "bits/stdc++.h"
 2 #include <vector>
 3 
 4 using namespace std;
 5 
 6 int T, N, A[100010], tmp, res, maxVal, l, r, m;
 7 
 8 // 看的別人的樹狀陣列模板,這個class可以不在初始化的時候接受arr的
 9 // 為了以後方便複用還是留著吧(
10 class BinaryIndexedTree {
11 public:
12     vector<int> bitArr;
13 
14     BinaryIndexedTree(int
arr[], int l = 0) { 15 bitArr.clear(); 16 bitArr.resize(l + 1, 0); 17 for (int i = 0; i < l; ++i) 18 bitArr[i + 1] = arr[i]; 19 int j; 20 for (int i = 1; i <= l; ++i) { 21 j = i + (i & -i); 22 if (j <= l) 23 bitArr[j] += bitArr[i];
24 } 25 } 26 27 void reset(int arr[], int l = 0) { 28 bitArr.clear(); 29 bitArr.resize(l + 1, 0); 30 for (int i = 0; i < l; ++i) 31 bitArr[i + 1] = arr[i]; 32 int j; 33 for (int i = 1; i <= l; ++i) { 34 j = i + (i & -i); 35 if (j <= l) 36 bitArr[j] += bitArr[i]; 37 } 38 } 39 40 void update(int idx, int val) { 41 ++idx; 42 while (idx < bitArr.size()) { 43 bitArr[idx] += val; 44 idx += idx & (-idx); 45 } 46 } 47 48 int prefixSum(int idx) { 49 ++idx; 50 int res = 0; 51 while (idx > 0) { 52 res += bitArr[idx]; 53 idx -= idx & (-idx); 54 } 55 return res; 56 } 57 58 int rangeSum(int withoutLeft, int withRight) { 59 return prefixSum(withRight) - prefixSum(withoutLeft); 60 } 61 }; 62 63 64 int main() { 65 scanf("%d", &T); 66 BinaryIndexedTree * binIndTree = new BinaryIndexedTree(A); 67 for (int _t = 1; _t <= T; ++_t) { 68 scanf("%d", &N); 69 printf("Case #%d:", _t); 70 res = 0; 71 maxVal = 1; 72 73 binIndTree->reset(A, 100005); 74 for (int i = 1; i <= N; ++i) { 75 scanf("%d", &tmp); 76 binIndTree->update(tmp, 1); 77 maxVal = max(tmp, maxVal); 78 79 l = res, r = maxVal; 80 while (l <= r) { 81 m = (l + r) >> 1; 82 if (m <= binIndTree->rangeSum(m - 1, maxVal)) { 83 res = m; 84 l = m + 1; 85 } 86 else { 87 r = m - 1; 88 } 89 } 90 printf(" %d", res); 91 } 92 printf("\n"); 93 } 94 return 0; 95 }