给你一个数组长度为 n n n的数组 a ( 1 ≤ a i ≤ n ) a\ (1\le a_i\le n) a (1≤ai≤n),有 q q q次操作,每次操作输入 k k k。
若 k > 0 k>0 k>0,数组中增加一个数 k k k
若 k < 0 k<0 k<0,数组中去掉第 − k -k −k 小的数
若最后数组为空,则输出0,否则输出任意一个数组中存在的数。
1.二分答案
2.权值线段树
3.树状数组改改
这是一道模板题,写这篇博客主要是给自己开拓思维,解法比较多。
#include
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 5;
const int N = 1e6 + 5;
int n,T;
int a[N],q[N];
bool check(int x){
int cnt=0;
for(int i=1;i<=n;i++) if(a[i]<=x) cnt++;
for(int i=1;i<=T;i++){
if(q[i]<0){
if(-q[i]<=cnt) cnt--;
}
else if(q[i]<=x) cnt++;
}
return cnt>0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>T;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=T;i++) cin>>q[i];
int L=1,R=n+1;
while(L<R){
int mid=(L+R)/2;
if(check(mid)) R=mid;
else L=mid+1;
}
cout<<(L<=n?L:0)<<'\n';
return 0;
}
#include
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 5;
const int N = 1e6 + 5;
int n,T;
int f[4*N];
void add(int l,int r,int v,int x,int t){
if(l==r) f[v]+=t;
else{
int mid=(l+r)/2;
if(x<=mid) add(l,mid,v*2,x,t);
else add(mid+1,r,v*2+1,x,t);
f[v]=f[v*2]+f[v*2+1];
}
}
int kth(int l,int r,int v,int k){
if(l==r) return l;
else{
int mid=(l+r)/2,s1=f[v*2],s2=f[v*2+1];
if(k<=s1) return kth(l,mid,v*2,k);
else return kth(mid+1,r,v*2+1,k-s1);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>T;
for(int i=1;i<=n;i++){
int x;cin>>x;
add(1,n,1,x,1);
}
for(int i=1;i<=T;i++){
int x;cin>>x;
if(x>0) add(1,n,1,x,1);
else add(1,n,1,kth(1,n,1,-x),-1);
}
if(!f[1]) cout<<0<<'\n';
else cout<<kth(1,n,1,1)<<'\n';
return 0;
}
#include
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 5;
const int N = 1048588;
const int lim = 1048576;
int n,T;
int bit[N];
void add(int pos,int val){
for(int i=pos;i<=lim;i+=i&(-i)) bit[i]+=val;
}
int bsearch(int x){
if(x==0) return 0;
int pos=0;
for(int i=lim/2;i>=1;i/=2){
if(bit[pos+i]<x){
x-=bit[pos+i];
pos+=i;
}
}
return pos+1;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>T;
for(int i=1;i<=n;i++){
int x;cin>>x;
add(x,1);
}
int cnt=n;
for(int i=1;i<=T;i++){
int x;cin>>x;
if(x>0) add(x,1),cnt++;
else{
x=bsearch(-x);
add(x,-1),cnt--;
}
}
cout<<(cnt==0?0:bsearch(1))<<'\n';
return 0;
}
int find_kth(int k)
{
int ans=0,sum=0,i;
for(int i=20;i>=0;i--)
{
ans+=(1<<i);
if(ans>=maxn||sum+bit[ans]>=k)
ans-=(1<<i);
else
sum+=bit[ans];
}
return ans+1;
}