[CF1179C]Serge and Dining Room

Serge and Dining Room

题解

很容易发现,当一个比赛能被选择时,当且仅当能够AK它的人比比它更难的比赛更多时。

于是,我们可以通过权值线段树维护选手的能力与比赛的难度,修改就单点修改就可以了。

查询就找到第一个为被选择的点输出即可。

时间复杂度O\left(nlog_{n} \right )

源码

#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;
}

谢谢!!!

你可能感兴趣的:(#,线段树,------贪心------)