给你一串数组a(有序),再给你q次操作,每次操作给你一个数k,如果k大于0,则将k按顺序插入到数组a中,若k小于0,则将数组中第 | k | 大的数删除,最后输出数组a中的任意一个数,若数组a中没有数则输出0
注意:该题内存限制为28M
最先想到用multiset去做,但是由于multiset是集合,没法像数组那样通过下标访问某个元素,遍历的话又会超时。。。。然后就恰饭去了。。。。
经大佬点播,用树状数组去维护每个数的个数,比如1,1,2,3,5中,1的个数就是2,即a[1]=2,用树状数组维护这个数组a。然后进行删除操作时用二分查找第k个数是哪个,再删除它。
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int N[1050000];
int n,q,k;
int lowbit(int x)
{
return x&(-x);}
void insertt(int x,int a)
{
while(x<=n)
{
N[x]+=a;
x+=lowbit(x);}
}
int query(int x,int y)
{
x--;
int ans1=0,ans2=0;
while(x>0)
{
ans1+=N[x];
x-=lowbit(x);}
while(y>0)
{
ans2+=N[y];
y-=lowbit(y);}
return ans2-ans1;
}
int ef(int x)
{
int l=1,r=n,ansl;
while(l<r)
{
int mid=(l+r)/2;
ansl=query(l,mid);
if(ansl<x)
{
l=mid+1;
x-=ansl;}
else
{
r=mid;}
}
return l;
}
int main()
{
int a,pos;
scanf("%d %d",&n,&q);
for(int i=1;i<=n;i++)
{
scanf("%d",&a);
insertt(a,1);
}
while(q--)
{
scanf("%d",&k);
if(k>0)
{
insertt(k,1);}
else
{
pos=ef(-k);
insertt(pos,-1);}
}
if(query(1,n)==0)
{
printf("0\n");}
else
{
pos=ef(1);
printf("%d\n",pos);
}
return 0;
}