单调队列求调
  • 板块灌水区
  • 楼主STA_Morlin
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/10/27 20:38
  • 上次更新2023/11/2 11:11:16
查看原帖
单调队列求调
347089
STA_Morlin楼主2023/10/27 20:38
#include <bits/stdc++.h>
namespace {
    #define filein(x) freopen(x".in", "r", stdin)
    #define fileout(x) freopen(x".out", "w", stdout)
    #define file(x) filein(x), fileout(x)
    using namespace std;
    #define ll long long
    #define db double
    #define pii pair<int, int>
    #define fir first
    #define sec second
    #define mp(x, y) make_pair(x, y)
    #define max(x, y) (x>y?x:y)
    #define min(x, y) (x<y?x:y)
    const int man = 1e5+10;
} ;

int n, d;
ll res, had;
int cst[man], lan[man]; // lan_i means site i should buy oil in site len_i.
ll dis[man];
queue<pii > q;
int main () {
    file("test");
    scanf("%d%d", &n, &d);
    for (int i = 2; i <= n; ++ i) scanf("%lld", dis+i), dis[i] += dis[i-1];
    for (int i = 1; i <= n; ++ i) scanf("%d", cst+i);
    q.push(mp(cst[1], 1));
    for (int i = 2; i <= n; ++ i) {
        while (cst[i] < q.front().fir) lan[q.front().sec] = i, q.pop();
        q.push(mp(cst[i], i));
    } while (q.size()) lan[q.front().sec] = n, q.pop();

    for (int i = 1; i < n; ++ i) {
        if (had*d >= dis[n]) break;
        if (had*d < dis[lan[i]]) 
            res += (ceil(dis[lan[i]]*1.0/d)-had)*cst[i], 
            had = ceil(dis[lan[i]]*1.0/d);
        
        // printf("%d, %lld %lld %d %lld\n", i, res, had, lan[i], dis[i]);
    } printf("%lld", res);
    return 0;
}

JT2

2023/10/27 20:38
加载中...