题解:AT_abc389_f [ABC389F] Rated Range

洛谷专栏链接

f x f_x fx 表示初始 Rated 为 x x x 参加完所有比赛能涨多少分。

证明 { x + f x } \{x+f_x\} {x+fx} 有单调性:

y ≤ x y\le x yx

对于一场比赛 [ L , R ] [L,R] [L,R],有如下情况:

  • L ≤ y ≤ R < x L\le y\le R<x LyR<x,参加完后仍然满足 y + 1 ≤ x y+1\le x y+1x
  • L ≤ y ≤ x ≤ R L\le y \le x\le R LyxR,参加完后仍然满足 y + 1 ≤ x + 1 y+1\le x+1 y+1x+1
  • y ≤ x ≤ L y \le x\le L yxL,参加完后仍然满足 y ≤ x y\le x yx

所以 { x + f x } \{x+f_x\} {x+fx} 具有单调性。

因此可以二分比赛 [ L , R ] [L,R] [L,R],原始 Rated ∈ [ l , r ] \in[l,r] [l,r] 能涨分。

用树状数组维护即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a[500005];
void add(int d,int x){
	while(d<=500000){
		a[d]+=x;
		d+=d&-d;
	}
}
int get(int d){
	int sum=0;
	while(d){
		sum+=a[d];
		d-=d&-d;
	}
	return sum;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		int l,r;
		cin>>l>>r;
		int L=1,R=500000;
		while(L<=R){
			int mid=(L+R)>>1;
			if(get(mid)+mid>=l)R=mid-1;
			else L=mid+1;
		}
		l=R+1;
		L=1,R=500000;
		while(L<=R){
			int mid=(L+R)>>1;
			if(get(mid)+mid<=r)L=mid+1;
			else R=mid-1;
		}
		r=L-1;
		if(r<l)continue;
		add(l,1);
		add(r+1,-1);
	}
	cin>>m;
	while(m--){
		int x;
		cin>>x;
		cout<<x+get(x)<<"\n";
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值