随笔 - 101  文章 - 0  评论 - 0  阅读 - 6118

聪明的质监员

P1314 [NOIP2011 提高组] 聪明的质监员 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

  • 二分思路
  • 当y>s时需要增大w来减小y
  • 当y<s时需要减小w来增大y
  • 所以y>s or y<s就成为judge函数返回值,用于控制w增大取右边还是减小取左边
  • judge函数内计算y值用前缀和的思想,pre_n代表个数,pre_v代表值,对每个区间用乘法计算
// https://www.luogu.com.cn/problem/P1314
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MAX 200005
ll n, m, pre_n[MAX], pre_v[MAX], v[MAX], w[MAX], ans, r[MAX], l[MAX], s, sum = 0x3f3f3f3f3f3f3f3f, max_w = -1, min_w = 2147483647;
void init()
{
    ans = 0;
    memset(pre_n, 0, sizeof(pre_n));
    memset(pre_v, 0, sizeof(pre_v));
}
bool judge(ll ww)
{
    init();
    for (ll i = 1; i <= n; i++)
        if (w[i] >= ww)
            pre_n[i] = pre_n[i - 1] + 1, pre_v[i] = pre_v[i - 1] + v[i];
        else
            pre_n[i] = pre_n[i - 1], pre_v[i] = pre_v[i - 1];
    for (ll i = 1; i <= m; i++)
    {
        ans += (pre_n[r[i]] - pre_n[l[i] - 1]) * (pre_v[r[i]] - pre_v[l[i] - 1]);
    }
    sum = min(sum, llabs(ans - s));
    return ans > s;
}
void input()
{
    cin >> n >> m >> s;
    for (ll i = 1; i <= n; i++)
    {
        scanf("%lld%lld", w + i, v + i);
        max_w = max(w[i], max_w);
        min_w = min(w[i], min_w);
    }
    for (int i = 1; i <= m; i++)
    {
        scanf("%lld%lld", l + i, r + i);
    }
}
int main()
{
    input();
    ll left = min_w - 1, right = max_w + 2;
    while (left <= right)
    {
        ll mid = (left + right) >> 1;
        if (judge(mid))
            left = mid + 1;
        else
            right = mid - 1;
    }
    printf("%lld", sum);
}

 

posted on   樵风  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示