CF1574C Slay the Dragon 题解

题目

链接

https://www.luogu.com.cn/problem/CF1574C

字面描述

题面翻译

给定长度为 n n n 的序列 a a a m m m 次询问,每次询问包含两个参数 x , y x,y x,y,你可以给序列任意位置 + 1 +1 +1,最后你需要找出一个位置 p p p ,满足

  • a p ≥ x a_p\ge x apx
  • ∑ i = 1 n a i [ i ≠ p ] ≥ y \displaystyle\sum_{i=1}^n a_i[i\not= p] \ge y i=1nai[i=p]y

最小化 + 1 +1 +1 次数,输出其次数。

限制 2 ≤ n ≤ 2 × 1 0 5 , 1 ≤ m ≤ 2 × 1 0 5 , 1 ≤ a i , x ≤ 1 0 12 , 1 ≤ y ≤ 1 0 18 2\le n\le2\times 10^5,1\le m\le 2\times10^5,1\le a_i,x\le 10^{12},1\le y\le 10^{18} 2n2×105,1m2×105,1ai,x1012,1y1018

Translated by 飞丞

题目描述

Recently, Petya learned about a new game “Slay the Dragon”. As the name suggests, the player will have to fight with dragons. To defeat a dragon, you have to kill it and defend your castle. To do this, the player has a squad of $ n $ heroes, the strength of the $ i $ -th hero is equal to $ a_i $ .

According to the rules of the game, exactly one hero should go kill the dragon, all the others will defend the castle. If the dragon’s defense is equal to $ x $ , then you have to send a hero with a strength of at least $ x $ to kill it. If the dragon’s attack power is $ y $ , then the total strength of the heroes defending the castle should be at least $ y $ .

The player can increase the strength of any hero by $ 1 $ for one gold coin. This operation can be done any number of times.

There are $ m $ dragons in the game, the $ i $ -th of them has defense equal to $ x_i $ and attack power equal to $ y_i $ . Petya was wondering what is the minimum number of coins he needs to spend to defeat the $ i $ -th dragon.

Note that the task is solved independently for each dragon (improvements are not saved).

输入格式

The first line contains a single integer $ n $ ( $ 2 \le n \le 2 \cdot 10^5 $ ) — number of heroes.

The second line contains $ n $ integers $ a_1, a_2, \dots, a_n $ ( $ 1 \le a_i \le 10^{12} $ ), where $ a_i $ is the strength of the $ i $ -th hero.

The third line contains a single integer $ m $ ( $ 1 \le m \le 2 \cdot 10^5 $ ) — the number of dragons.

The next $ m $ lines contain two integers each, $ x_i $ and $ y_i $ ( $ 1 \le x_i \le 10^{12}; 1 \le y_i \le 10^{18} $ ) — defense and attack power of the $ i $ -th dragon.

输出格式

Print $ m $ lines, $ i $ -th of which contains a single integer — the minimum number of coins that should be spent to defeat the $ i $ -th dragon.

样例 #1

样例输入 #1
4
3 6 2 3
5
3 12
7 9
4 14
1 10
8 7
样例输出 #1
1
2
4
0
2

提示

To defeat the first dragon, you can increase the strength of the third hero by $ 1 $ , then the strength of the heroes will be equal to $ [3, 6, 3, 3] $ . To kill the dragon, you can choose the first hero.

To defeat the second dragon, you can increase the forces of the second and third heroes by $ 1 $ , then the strength of the heroes will be equal to $ [3, 7, 3, 3] $ . To kill the dragon, you can choose a second hero.

To defeat the third dragon, you can increase the strength of all the heroes by $ 1 $ , then the strength of the heroes will be equal to $ [4, 7, 3, 4] $ . To kill the dragon, you can choose a fourth hero.

To defeat the fourth dragon, you don’t need to improve the heroes and choose a third hero to kill the dragon.

To defeat the fifth dragon, you can increase the strength of the second hero by $ 2 $ , then the strength of the heroes will be equal to $ [3, 8, 2, 3] $ . To kill the dragon, you can choose a second hero.

代码实现

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn=2e5+10;
int n,m;
ll tot;
ll a[maxn];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		tot+=a[i];
	}
	sort(a+1,a+n+1);
	scanf("%d",&m);
	while(m--){
		ll x,y;
		scanf("%lld%lld",&x,&y);
		if(tot<x+y){
			if(a[1]>x){
				printf("%lld\n",y-(tot-a[1]));
				continue;
			}
			int l=1,r=n;
			while(l<=r){
				int mid=l+r>>1;
				if(a[mid]>x)r=mid-1;
				else if(a[mid]<x)l=mid+1;
				else break;
			}
			int op=l+r>>1;
			if(y<=tot-a[op])printf("%lld\n",x-a[op]);
			else printf("%lld\n",x-a[op]+y-(tot-a[op]));
			continue;
		}
		else{
			if(a[1]>x){
				if(y>tot-a[1])printf("%lld\n",y-(tot-a[1]));
				else printf("0\n");
				continue;
			}
			int l=1,r=n;
			while(l<=r){
				int mid=l+r>>1;
				if(a[mid]>x)r=mid-1;
				else if(a[mid]<x)l=mid+1;
				else break;
			}
			int op=l+r>>1;
			int op1=op+1;
			if(tot==x+y){
				if(op1<=n)printf("%lld\n",min(x-a[op],a[op1]-x));
				else printf("%lld\n",x-a[op]);
			}
			else{
				if(y<=tot-a[op1]){
					if(op1<=n)printf("0\n");
					else printf("%lld\n",x-a[op]);
				}
				else {
					if(op1<=n)printf("%lld\n",min(x-a[op],y-(tot-a[op1])));
					else printf("%lld\n",x-a[op]);
				}
			}
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Yxz_

我只是一名ssfoier

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值