【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 }