NC16597 聪明的质监员

思路分析:
若要|y-s|的值越小,则y跟s越接近越好.

二分check:
若y>s, 则减小y, 根据检验公式可知需要增大m;
若y<s, 则增大y, 需要减小m.
这样可以让y跟s不断的接近.

检验公式的计算可以通过前缀和优化.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
typedef long double ld;
const ll mod = 1e9 + 7;
const double PI = acos(-1.0);
const double eps = 1e-10;
const ll inf = 1e18;
const int maxn = 200005;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar())    s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; }
inline void write(ll x) { if (!x) { putchar('0'); return; } char F[40]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-');    int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';        tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll qpow(ll a, ll b) { ll ans = 1;    while (b) { if (b & 1)    ans *= a;        b >>= 1;        a *= a; }    return ans; }    ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; }
inline int lowbit(int x) { return x & (-x); }
ll ans = inf;
ll n, m, s;
int w[maxn], v[maxn];
int qu[maxn][2];
ll b;	
ll sum[maxn], mul[maxn];

bool check(ll k) 
{

	for (int i = 1; i <= n; ++i)
	{
		if (w[i] >= k)
		{
			sum[i] = sum[i-1] + 1;
			mul[i] = mul[i-1] + v[i];
		}
		else
		{
			sum[i] = sum[i-1];
			mul[i] = mul[i-1];
		}
	}

	ll y =0;
	for (int i = 1; i <= m; ++i)
	{
		y += (sum[qu[i][1]] - sum[qu[i][0]-1] ) * (mul[qu[i][1]] - mul[qu[i][0]-1]);	
	}
	b = abs(s-y); 
	return y > s;
}
int main(int argc, char const *argv[])
{
	cin >> n >> m >> s;
	for (int i = 1; i <= n; ++i)
		cin >> w[i] >> v[i];
	for (int i = 1; i <= m; ++i)
		cin >> qu[i][0] >> qu[i][1];

	ll left = 0, right = 1e9;
	ll mid;
	while(left <= right)
	{
		mid = left + ((right - left) >> 1);
		if (check(mid))
		{
			left = mid + 1;
		}
		else
		{
			right = mid - 1;
		}
		ans = min(ans, b);
	}
	cout << ans << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值