很容易发现,当一个比赛能被选择时,当且仅当能够AK它的人比比它更难的比赛更多时。
于是,我们可以通过权值线段树维护选手的能力与比赛的难度,修改就单点修改就可以了。
查询就找到第一个为被选择的点输出即可。
时间复杂度。
#include
using namespace std;
#define MAXN 300005
#define MAXM 1000005
#define lowbit(x) (x&-x)
typedef long long LL;
typedef pair pii;
const LL mo=1e9+7;
const LL INF=0x7f7f7f7f;
template
_T Fabs(_T x){return x<0?-x:x;}
int n,m,q,a[MAXN],b[MAXN],cnt[MAXM];
int val[MAXM<<2],lzy[MAXM<<2];
bool cmp(int x,int y){return x>y;}
void pushdown(int rt){
if(!lzy[rt])return ;
val[rt<<1]+=lzy[rt];val[rt<<1|1]+=lzy[rt];
lzy[rt<<1]+=lzy[rt];lzy[rt<<1|1]+=lzy[rt];
lzy[rt]=0;
}
void pushup(int rt){val[rt]=min(val[rt<<1],val[rt<<1|1]);}
void build(int rt,int l,int r){
if(l==r)return (void)(val[rt]=1e6);
int mid=l+r>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void modify(int rt,int l,int r,int al,int ar,int aw){
if(al<=l&&r<=ar){val[rt]+=aw;lzy[rt]+=aw;return ;}
int mid=l+r>>1;pushdown(rt);
if(al<=mid)modify(rt<<1,l,mid,al,ar,aw);
if(ar>mid)modify(rt<<1|1,mid+1,r,al,ar,aw);
pushup(rt);
//printf("%d %d %d:%d\n",rt,l,r,val[rt]);
}
int query(int rt,int l,int r){
if(val[rt]>=0)return -1;
//printf("%d %d %d:%d\n",rt,l,r,val[rt]);
if(l==r)return l;int mid=l+r>>1;pushdown(rt);
if(val[rt<<1|1]<0)return query(rt<<1|1,mid+1,r);
if(val[rt<<1]<0)return query(rt<<1,l,mid);
return -1;
}
signed main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++)scanf("%d",&b[i]);
scanf("%d",&q);build(1,1,1e6);
//sort(a+1,a+n+1,cmp);sort(b+1,b+m+1);
for(int i=1;i<=n;i++){
if(!cnt[a[i]])modify(1,1,1e6,a[i],a[i],-1e6);
cnt[a[i]]++;modify(1,1,1e6,1,a[i],-1);
}
for(int i=1;i<=m;i++)modify(1,1,1e6,1,b[i],1);
while(q--){
int opt,i,x;scanf("%d %d %d",&opt,&i,&x);
if(opt==1){
modify(1,1,1e6,1,a[i],1);cnt[a[i]]--;
if(!cnt[a[i]])modify(1,1,1e6,a[i],a[i],1e6);a[i]=x;
if(!cnt[a[i]])modify(1,1,1e6,a[i],a[i],-1e6);
cnt[a[i]]++;modify(1,1,1e6,1,a[i],-1);
printf("%d\n",query(1,1,1e6));
}
else{
modify(1,1,1e6,1,b[i],-1);b[i]=x;
modify(1,1,1e6,1,b[i],1);
printf("%d\n",query(1,1,1e6));
}
}
return 0;
}