POJ2104 K-th Number(归并树)
平方分割一直TLE,最后用归并树处理过了,使用STL会比较慢。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<vector> #include<cmath> #include<utility> using namespace std; typedef long long LL; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 const int N = 100008, INF = 0x3F3F3F3F; int tp[N], a[N]; vector< int > v[N << 2]; void build( int l, int r, int rt){ if (l == r){ v[rt].clear(); v[rt].push_back(a[l]); } else { int mid = (l + r) >> 1; build(lson); build(rson); v[rt].resize(r - l + 1); merge(v[rt << 1].begin(), v[rt << 1].end(), v[rt << 1 | 1].begin(), v[rt << 1 | 1].end(), v[rt].begin()); } } int query( int a, int b, int l, int r, int rt, int x){ if (a <= l && b >= r){ return upper_bound(v[rt].begin(), v[rt].end(), x) - v[rt].begin(); } int mid = (l + r) >> 1; int cnt = 0; if (a <= mid){ cnt += query(a, b, lson, x); } if (b > mid){ cnt += query(a, b, rson, x); } return cnt; } int main(){ int n, q; while (~ scanf ( "%d %d" , &n, &q)){ for ( int i = 0; i < n; i++){ scanf ( "%d" , &a[i]); tp[i] = a[i]; } build(0, n - 1, 1); sort(tp, tp + n); int cnt = unique(tp, tp + n) - tp; while (q--){ int a, b, k; scanf ( "%d %d %d" , &a, &b, &k); a--; b--; int l = 0, r = cnt; while (l < r){ int mid = (l + r ) >> 1; if (query(a, b, 0, n - 1, 1, tp[mid]) < k){ l = mid + 1; } else { r = mid; } } printf ( "%d\n" , tp[l]); } } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步