题目大意:
给你一个长度为 n n n的序列,以及 q q q次询问 q i qi qi,如果 q i > 0 qi>0 qi>0,在序列中插入 q i qi qi,如果 q i < 0 qi<0 qi<0,在序列中删除第 ∣ q i ∣ |qi| ∣qi∣大的数,问你 q q q询问后,如果序列中为空,输出 0 0 0即可,否则输出序列中任意一个数即可。
思路:
所有操作无非就是删除第 k k k大数,增加第 k k k大数,我们可以用桶排序的思路建立线段树我们称为它为权值线段树,这个题 n = 1 e 6 n=1e6 n=1e6用权值线段树时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)是可以过的,但是结构体开不了会超空间这里要换一种存储方式,然后就是线段树的单点更新,单点询问操作(都很简单),还有权值线段树的第 k k k大操作(相当于前缀和也很简单)。
代码:
#include
using namespace std;
const int maxn = 1e6 + 10;
int tree[maxn << 2];
void update(int rt,int x,int l,int r){
if(l == r && l == x){
tree[rt]++;
return ;
}
int mid = l + r >> 1;
if(x <= mid)update(rt << 1,x,l,mid);
else update(rt << 1 | 1,x,mid + 1,r);
tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}
bool check(int rt,int id,int l,int r){
if(l == r && l == id){
if(tree[rt] > 0)return true;
else return false;
}
int mid = l + r >> 1;
if(id <= mid)return check(rt << 1,id,l,mid);
else return check(rt << 1 | 1,id,mid + 1,r);
}
void kth(int rt,int k,int l,int r){
if(l == r){
tree[rt]--;return;
}
int mid = l + r >> 1;
if(tree[rt << 1] >= k)kth(rt << 1,k,l,mid);
else kth(rt << 1 | 1,k - tree[rt << 1],mid + 1,r);
tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}
void solved(){
int n,q;scanf("%d%d",&n,&q);
for(int i = 1; i <= n; i++){
int x;scanf("%d",&x);
update(1,x,1,n);
}
for(int i = 1; i <= q; i++){
int x;scanf("%d",&x);
if(x > 0)update(1,x,1,n);
else {
x *= -1;kth(1,x,1,n);
}
}
if(tree[1] <= 0){
printf("0\n");
}else{
for(int i = 1; i <= n; i++){
if(check(1,i,1,n)){
cout<<i<<endl;break;
}
}
}
}
int main(){
solved();
return 0;
}
数组数组做法,其实和桶排序类似。
代码:
#include
using namespace std;
const int maxn = 1e6 + 10;
struct bit{
int c[maxn];
int lowbit(int x){
return x & -x;
}
void update(int x,int v = 1){
for(; x <= maxn; x += lowbit(x)){
c[x] += v;
}
}
int query(int x){
int s = 0;
for(; x ; x -= lowbit(x)){
s += c[x];
}
return s;
}
}BIT;
void solved(){
int n,q;scanf("%d%d",&n,&q);
for(int i = 1; i <= n; i++){
int x;scanf("%d",&x);BIT.update(x);
}
for(int i = 1; i <= q; i++){
int x;scanf("%d",&x);
if(x > 0)BIT.update(x);
else{
x *= -1;
int l = 1,r = n;
while(l < r){
int mid = l + r >> 1;
if(BIT.query(mid) >= x)r = mid;
else l = mid + 1;
}
BIT.update(r,-1);
}
}
int ans = BIT.query(n);
if(ans <= 0){
cout<<"0"<<endl;
}else{
for(int i = 1; i <= n ; i++){
if(BIT.query(i) - BIT.query(i - 1) > 0){
cout<<i<<endl;break;
}
}
}
}
int main(){
solved();
return 0;
}