• noip模拟赛 fateice-shop


    题目背景

    紫女,韩国歌舞坊(实为刺客组织)紫兰轩之主,千娇百媚,美艳无方。武艺高强且极有谋略胆识,精通奇石药物,冶炼之术及制毒用毒之术独步天下,真实姓名与来历无人知晓,只因总是身着一袭紫衣,所以众人以“紫女”称之。与公子韩非共同创建了“流沙”组织。

    题目描述

    为了能够获取更多的韩国内部消息,紫女决定收购一批极为罕见的稀世珍宝在紫兰轩进行拍卖,以吸引更多的大人物前来紫兰轩。她准备在m天内购买一些宝物来充实库存。现在,市场上有n种物品,第i种物品的价格为vi,紫女每天最多只能购买xi个。第i天紫女得到wi的钱,她会选择不停购买能买得起的最贵的物品。她想在尽量短的时间内做出决断,所以她需要提前求出每天会购买多少个物品。

    由于持有现金非常的危险,每一天买完东西后如果还剩下钱,这些钱就会被丢弃。

    输入输出格式

    输入格式:

    第一行两个整数n,m。接下来n行每行两个整数vi,xi。接下来m行每行一个整数wi。

    输出格式:

    m行每行一个整数,第i行表示第i天购买的物品数量。

    输入输出样例

    输入样例#1:
    3 3
    1 1
    2 2
    3 3
    5
    10
    15
    
    输出样例#1:
    2
    4
    6
    

    说明

    对于20%的数据,n,m<=1000。

    对于另外40%的数据,xi=1。

    对于100%的数据,n,m<=100000,1<=vi<=10^9,1<=xi<=10000,0<=wi<=10^18。

    分析:主要的思想还是二分吧.

          每次要找到<=w的最大的价格,我们可以先对原序列按照价格排个序,然后二分来找.找到以后我们看从这个物品往前买能买到哪,买多少个,这里可以用前缀和+二分解决,如果当前商品买不完就计算一下能买多少个.每次下来w都会减小,我们就不断地缩小右边界不停地二分就可以了.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    
    struct node
    {
        ll v, x;
    }e[100010];
    
    ll n, m;
    ll sum[100010], w, sum2[100010],ans;
    bool flag = false;
    
    bool cmp(node a, node b)
    {
        return a.v < b.v;
    }
    
    int erfen(ll maxn)
    {
        ll pos = 0, pos2 = 0;
        ll l = 1, r = maxn;
        while (l <= r)
        {
            ll mid = (l + r) >> 1;
            if (e[mid].v <= w)
            {
                pos = mid;
                l = mid + 1;
            }
            else
                r = mid - 1;
        }
        if (!pos)
        {
            flag = 1;
            return 0;
        }
        l = 1, r = pos;
        pos2 = pos;
        while (l <= r)
        {
            ll mid = (l + r) >> 1;
            if (sum[pos] - sum[mid] <= w)
            {
                pos2 = mid;
                r = mid - 1;
            }
            else
                l = mid + 1;
        }
        w -= sum[pos] - sum[pos2];
        ans += sum2[pos] - sum2[pos2];
        ll use = e[pos2].x;
        
        while (w >= e[pos2].v && use)
        {
            use--;
            w -= e[pos2].v;
            ans++;
        }
        if (use == 0)
            return pos2 - 1;
        else
            return pos2;
    }
    
    int main()
    {
        scanf("%lld%lld", &n, &m);
        for (int i = 1; i <= n; i++)
            scanf("%lld%lld", &e[i].v, &e[i].x);
        sort(e + 1, e + n + 1, cmp);
        for (int i = 1; i <= n; i++)
        {
            sum[i] = sum[i - 1] + e[i].v * e[i].x;
            sum2[i] = sum2[i - 1] + e[i].x;
        }
        while (m--)
        {
            flag = 0;
            scanf("%lld", &w);
            ans = 0;
            int t = erfen(n);
            while (!flag && w >= e[1].v && t > 0)
                t = erfen(t);
            printf("%lld
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    制作yaffs2文件系统
    nandwrite 参数
    linux并发控制之信号量
    mke2fs 制作ext2文件系统image
    stat文件状态信息结构体
    mount命令详解
    fiddler——http——cookie
    fiddler——http——请求方法、状态码
    http的cookie
    fiddler——http——header首部(请求首部和响应首部)——个人文档整理
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7670688.html
Copyright © 2020-2023  润新知