HDU 4417 (二分 + 区间第k大)
2016-07-19 14:22
369 查看
题目:
查询区间【L,R】中有多少数 比给定的 H 小。分析:
我们可以这么想, H 一定会比 区间的第 X 大 ,第 X +1 小。怎么确定 X。
这是一个单调的问题, 所以二分 + 区间第 K 大就可以确定了。
Code:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const int maxn = 100000 + 131; int sorted[maxn]; int tree[30][maxn]; int toleft[30][maxn]; void Build(int l, int r, int dep) { if(l == r) return ; int mid = (l + r) >> 1; int same = mid - l + 1; for(int i = l; i <= r; ++i) if(tree[dep][i] < sorted[mid]) same--; int lpos = l, rpos = mid + 1; for(int i = l; i <= r; ++i) { if(tree[dep][i] < sorted[mid]) tree[dep+1][lpos++] = tree[dep][i]; else if(tree[dep][i] == sorted[mid] && same > 0) tree[dep+1][lpos++] = tree[dep][i], same--; else tree[dep+1][rpos++] = tree[dep][i]; toleft[dep][i] = toleft[dep][l-1] + lpos - l; } Build(l,mid,dep+1), Build(mid+1, r, dep+1); } int Query(int L, int R, int l, int r, int dep, int k) { if(l == r) return tree[dep][l]; int mid = (L + R) >> 1; int cnt = toleft[dep][r] - toleft[dep][l-1]; if(cnt >= k) { int newl = L + toleft[dep][l-1]-toleft[dep][L-1]; int newr = newl + cnt -1; return Query(L,mid,newl, newr,dep+1, k); } else { int newr = r + toleft[dep][R] - toleft[dep][r]; int newl = newr -(r-l-cnt); return Query(mid+1,R, newl, newr,dep+1, k-cnt); } } int main() { int n, m, T; ios::sync_with_stdio(false); cin >> T; for(int kase = 1; kase <= T; ++kase) { memset(tree,0,sizeof(tree)); cin >> n >> m; for(int i = 1; i <= n; ++i) cin >> tree[0][i], sorted[i] = tree[0][i]; sort(sorted+1, sorted+1+n); Build(1,n,0); printf("Case %d:\n",kase); while(m--) { int s, t, h; cin >> s >> t >> h; s++, t++; int ans = 0; int l = 1, r = (t-s) + 1; while(l <= r) { int mid = (l + r) >> 1; int temp = Query(1,n,s,t,0,mid); if(temp <= h) { ans = mid; l = mid + 1; } else r = mid - 1; } printf("%d\n",ans); } } return 0; }
相关文章推荐
- 快速排序里的学问:从猜数字开始
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- Search Insert Position,Search for a Range,Pow(x, n),Sqrt(x)
- Find Minimum in Rotated Sorted Array II
- [LeetCode] Sqrt(x)
- [LeetCode] Pow(x, n)
- [LeetCode] Search Insert Position
- [LeetCode] Search for a Range
- [LeetCode] Search in Rotated Sorted Array
- PAT 1057 Stack (30)
- int sqrt(int x)
- Pow(x, n)
- Find Minimum in Rotated Sorted Array
- Divide Two Integers
- 信息竞赛学习笔记:POJ3579中位数(二分)
- acm解题报告 HDU 2141 Can you find it?
- acm解题报告 HDU 2199 Can you solve this equation?
- acm解题报告 HDU 2899 Strange fuction
- acm解题报告 HDU 1969 Pie
- acm解题报告 HDU 1061 Rightmost Digit