长沙现场赛A题

题目大意

Hint:虽然是最水的题,但是现场赛我们没有过,让我感觉非常捉急,所以现在我把这道题我的解法挂出来……话说我并没有参与A题……
题目大意就有一种东西,当你买不少于si件的时候,需要付pi的单价,现在给定所有的s和p,然后每次告诉你买多少件,问最少花多少钱。题目保证s逐级递增,p逐级递减。

解题思路

既然题目已经保证了随着s的递增,pi是递减的,那么这道题的策略就少了,对于每一个询问q,我们不可能把它分成几部分来买,因为那样每一部分都会多花钱,那么只有两种策略,一种是在当前它所在区间的价格下买正好的,一种是买比它多的,但是单价少总价会省钱的,现在问题就是如何确定用什么样的策略。
首先,这道题相当于告诉我们,对于每一种东西,如果多买,我们一定恰好买某一个si件,因为如果多买就会多花钱,那么就简单了,在他多买的情况下,我们可以得到他多买的所有的情况,在这所有的情况里面求一个最小值,与买正好的对比一下就可以了……
对于最小值,有很多种处理方式,写一个RMQ,线性预处理,或者像我这种只会用线段树写的……

参考代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
typedef long long LL;
const int maxn = (int)1e5 + 10;
const long long INF = (LL)1 << 62;
LL s[maxn], p[maxn], mi[maxn << 2];
void PushUp(int rt){
    mi[rt] = min(mi[rt << 1], mi[rt << 1 | 1]);
}
void build(int l, int r, int rt){
    if (l == r){
        mi[rt] = s[l] * p[l];
        return;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    PushUp(rt);
}
LL query(int ll, int rr, int l, int r, int rt){
    if (ll <= l && rr >= r) return mi[rt];
    int m = (l + r) >> 1;
    LL ret = INF;
    if (ll <= m) ret = min(ret, query(ll, rr, lson));
    if (rr > m) ret = min(ret, query(ll, rr, rson));
    return ret;
}
int n, m;
void solve(){
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%lld%lld", &s[i], &p[i]);
    build(1, n, 1);
    while(m--){
        int x; scanf("%d", &x);
        int pos = lower_bound(s, s + n, x) - s;
        if (s[pos] > x) pos -= 1;
        LL x1 = query(pos + 1, n, 1, n, 1);
        LL x2 = x * p[pos];
        LL ans = x1 > x2 ? x2 : x1;
        printf("%lld\n", ans);
    }
}
int main(){
    int cs; scanf("%d", &cs);
    while(cs--) solve();
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值