感受
权值线段树模板题,随便搞一搞
思路
很显然,每次往后推一个数时,只要求出已覆盖数的第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;
}



京公网安备 11010502036488号