感受
权值线段树模板题,随便搞一搞
思路
很显然,每次往后推一个数时,只要求出已覆盖数的第k大,明显就是板子题目呀!
叶子节点维护的是小与等于这个权值的有多少个,可以离散化乱搞
#include <bits/stdc++.h> #define ls o << 1 #define rs o << 1 | 1 using namespace std; typedef long long ll; const int maxn = 1e4+ 10; vector<int> vec; int a[maxn << 2];///叶子节点表示小与等于这个权值的有多少个 int b[maxn]; int c[maxn]; void up(int o){ a[o] = a[ls] + a[rs]; } void update(int o, int l, int r, int x){ if(l == r){ a[o]++; return ; } int mid = (l + r) / 2; if(x <= mid) update(ls, l, mid, x); else update(rs, mid + 1, r, x); up(o); } int num; void query(int o, int l, int r, int k){ if(l == r){ num = l; return ; } int mid = (l + r) / 2; if(k > a[ls]) query(rs, mid + 1, r, k - a[ls]); else query(ls, l, mid, k); } int main(){ int t; int opt, m; scanf("%d", &t); while(t--){ scanf("%d%d", &opt, &m); for(int i = 1; i <= m; i++){ scanf("%d", &c[i]); b[i] = c[i]; } sort(b + 1, b + m + 1); memset(a, 0, sizeof(a)); vec.clear(); for(int i = 1; i <= m; i++){ int pos = lower_bound(b + 1, b + m + 1, c[i]) - b; update(1, 1, m, pos); if(i & 1){ query(1, 1, m, (i + 1) / 2); vec.push_back(b[num]); } } num = vec.size(); printf("%d %d\n", opt, num); int pp = 0; for(int i = 0; i < num; i++){ printf("%d", vec[i]); pp++; if(pp % 10 && i != num - 1){ putchar(' '); } else{ putchar('\n'); pp = 0; } } } return 0; }