首页 > 其他分享 >ABC348G题解

ABC348G题解

时间:2024-04-08 09:56:37浏览次数:32  
标签:le int 题解 back mid gl fl ABC348G

令 \(f_i\) 为当 \(k=i\) 时的答案。令 \(g_i\) 为 \(f_i+\max\limits_{j\in S} b_j\)。也就是不减去 \(b\) 的最大值的结果。

直接做是 \(O(n^2)\) 的,考虑分治,令两个子问题的 \(f,g\) 分别为 \(fl,gl\) 和 \(fr, gr\)。

合并的时候做一个

\[f_i=\max(\max\limits_{c+d=i}(gl_c+fr_d),\max(fl_i,fr_i)) \]

\[g_i=\max\limits_{j+k=i}(gl_j+gr_k) \]

即可。

但是 \((\max,+)\) 卷积怎么做?

对于 \(g\),因为递归到最小的子问题时,得到的 \(g\) 是上凸函数,所以合并后的 \(g\) 仍然是上凸的,直接闵可夫斯基和就做完了。

对于 \(f\),\(f\) 并不是凸的,但是 \(g\) 是凸的,考虑是否有决策单调性。结论是:有。

设 \(p_i\) 为 \(f_i\) 的决策点,即 \(f_i=fr_{p_i} + gl_{i - p_i}\)。

令 \(w(a,b)=gl_{b-a}\)。

接下来证明 \(w(a-1,b+1)+w(a,b)\le w(a-1,b)+w(a,b+1)\)。

设 \(x=b-a+1\)。

则变为证明 \(g_{x+1}+g_{x-1}\le 2\times g_x\)。

设 \(k_x=g_{x+1}-g_x\)。因为 \(g\) 上凸,所以 \(k_x\) 单调不增。

所以 \(g_{x+1}+g_{x-1}=2\times g_{x-1} + k_{x-1}+k_x,2\times g_x=2\times g_{x-1}+2\times k_{x-1}\)。

因为 \(k_x\le k_{x-1}\),所以原式成立。

接下来证明 \(p_i\) 单调。考虑反证法:

若存在大于 \(i\) 的 \(c\) 使得 \(p_c<p_i\),则有:

\[f_c=fl_{p_c} + w(p_c,c)\\ f_i=fl_{p_i} + w(p_i,i) \]

那么 \(f_i+f_c=fl_{p_c} + w(p_c,c)+fl_{p_i} + w(p_i,i)\)。

根据四边形不等式,因为 \(p_c<p_i,c>i\),所以 \(w(p_c,c)+w(p_i,i)\le w(p_c,i)+w(p_i,c)\)。

所以有 \(f_c+f_i\le fl_{p_c} + w(p_c,i)+fl_{p_i} + w(p_i,c)\)。但又有 \(fl_{p_c}+w(p_c,i)\le f_i,fl_{p_i}+w(p_i,c)\le f_i\),也就是说当且仅当四边形不等式取等时成立,这时只令 \(p_c=p_i\) 即可。

所以有决策单调性,简单的二分队列优化一下 dp 就行了。常数小跑得飞快。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 2e5 + 5;
const ll inf = 1e18;

int n;
struct node {ll a, b;} a[N];

pair<vector<ll>, vector<ll>> solve(int l, int r)
{
    if(l > r) return {{}, {0}};
    if(l == r) return {{a[l].a}, {0, a[l].a - a[l].b}};
    int mid = l + r >> 1;
    int len = r - l + 1;
    auto L = solve(l, mid);
    auto R = solve(mid + 1, r);
    vector<ll> &fr = R.second;
    vector<ll> &gl = L.first;
    vector<ll> f(len + 1, 0);
    vector<ll> g(len);
    merge(gl.begin(), gl.end(), R.first.begin(), R.first.end(), g.begin(), greater<ll>());
    for(int i = 1; i < gl.size(); i ++) gl[i] += gl[i - 1];
    gl.insert(gl.begin(), 0);
    struct node {int l, r, v;};
    deque<node> q; q.push_back({1, len, 1});
    auto calc = [&](int pos, int v) {if(pos - v >= gl.size()) return -inf; return fr[v] + gl[pos - v];};
    for(int i = 1; i < fr.size(); i ++)
    {
        f[i] = calc(i, q.front().v);
        q.front().l ++;
        if(q.front().l > q.front().r) q.pop_front();
        while(q.size() && calc(q.back().l, q.back().v) <= calc(q.back().l, i)) q.pop_back();
        int pl = n + 1;
        if(q.size())
        {
            int L = q.back().l, R = q.back().r + 1, nowv = q.back().v;
            while(L < R)
            {   
                int mid = L + R >> 1;
                if(calc(mid, i) < calc(mid, nowv)) L = mid + 1;
                else R = mid;
            }
            q.back().r = R - 1;
            if(q.back().l > q.back().r) q.pop_back();
            pl = R;
        }
        else pl = i + 1;
        if(pl <= len) q.push_back({pl, len, i});
    }
    for(auto [l, r, v] : q)
        for(int i = l; i <= r; i ++)
            f[i] = calc(i, v);
    for(int i = 1; i < L.second.size(); i ++) f[i] = max(f[i], L.second[i]);
    for(int i = 1; i < R.second.size(); i ++) f[i] = max(f[i], R.second[i]);
    return {g, f};
}

const int maxn = (1 << 22) + 5;
char buf[maxn], *S = buf, *T = buf;
char gc() {return (S == T) ? (T = (S = buf) + fread(buf, 1, maxn, stdin), (S == T) ? EOF : *S ++) : (*S ++);}
template<typename T>
void read(T &x)
{
    x = 0; char c = gc(); bool f = 0;
    while(c < '0' || c > '9') f |= c == '-', c = gc();
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc();
    if(f) x = -x;
}

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    read(n);
    for(int i = 1; i <= n; i ++) read(a[i].a), read(a[i].b);
    sort(a + 1, a + n + 1, [](node &x, node &y) {return x.b < y.b;});
    vector<ll> ans = solve(1, n).second;
    for(int i = 1; i <= n; i ++)
        cout << ans[i] << "\n";

    return 0;
}

标签:le,int,题解,back,mid,gl,fl,ABC348G
From: https://www.cnblogs.com/adam01/p/18120487

相关文章

  • 蓝桥杯嵌入式2023年第十四届省赛主观题解析
    1 题目2 代码/*Includes------------------------------------------------------------------*/#include"main.h"#include"adc.h"#include"rtc.h"#include"tim.h"#include"gpio.h"/*Privateinclud......
  • Hetao P1178 冒险者 题解 [ 绿 ][ 最短路 ][ 线性 dp ]
    原题题解本蒟蒻采用的和大部分人解法不同,是根据当前标记值的总和跑最短路的一种解法。思路30min,调代码2h的我太蒻了首先观察题面可以发现本题求的是最少操作数,由于要求最小且有变化的过程,所以可以使用dp求解,也可以使用最短路算法求解,本篇先介绍最短路的算法。其实......
  • ABC218E Destruction题解
    ABC218EDestruction题解题意给你一个\(n\)个点\(m\)条边的带权无向联通图,你可以删去任意条边,要求保证图联通的情况下删去边的权值和最大。\((n\le2\cdot10^5\,\m\le2\cdot10^5\,\-10^9\lee_i\le10^9)\)(\(e_i\)为边权)分析首先我们考虑边权全为正的情况,那么我们删......
  • 【解题报告】RbOI Round 1,A&D题解
    【RbOIR1】A&D题解其他题题解请移步B、C点击图片跳转比赛:A.AnxiousRobin从左到右扫一遍,按照题意模拟即可。这里解释一下我的代码:因为只判断了六种字母,所以遇到-会直接过滤,无需特判。展开代码#include<bits/stdc++.h>#definelllonglong#defineMyWifeCrista......
  • 图的遍历试题解析
    一、单项选择题01.下列关于广度优先算法的说法中,正确的是(A ).Ⅰ.当各边的权值相等时,广度优先算法可以解决单源最短路径问题Ⅱ.当各边的权值不等时,广度优先算法可用来解决单源最短路径问题Ⅲ.广度优先遍历算法类似于树中的后序遍历算法Ⅳ.实现图的广度优先算法时,使用的......
  • 关于layui的单图片上传遇坑-field-input-name问题解决
    直接上代码注意field:'ymftimage'layui.use(function(){varupload=layui.upload;varlayer=layui.layer;varelement=layui.element;var$=layui.$;//单图片上传varuploadInst=upload.render({elem:'#ID-upload-demo-btn',......
  • ARC175 A~C 题解
    ARC175ASpoonTakingProblem题目大意有\(n\)个人围成一个环,第\(i\)个人左手边是第\(i\)个勺子,右手边是第\(i\%n+1\)个勺子。每个人的惯用手用一个字符\(a_i=\)L/R/?表示,即左手/右手/未知。给定\(1\simn\)的一个排列\(P_1,\dots,P_n\)表示这\(n\)个人行动的......
  • 货币系统—背包问题—python题解
    题目链接:货币系统题目描述:给定V种货币(单位:元),每种货币使用的次数不限。不同种类的货币,面值可能是相同的。现在,要你用这V种货币凑出N元钱,请问共有多少种不同的凑法。输入格式第一行包含两个整数V和N。接下来的若干行,将一共输入V个整数,每个整数表示一种货币的......
  • 5G网络建设【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目-5G网络建设现需要在某城市进行5G网络建设,已经选取N个地点设置5G基站,编号固定为1到N,接下来需要各个基站之间使用光纤进行连接以确保基站能互联互通,不同基站之间架设光纤的成本各不相同,且有些节点之间已经存在光纤相连,请你设计算法,计算出能联通这些基站的最小成本是......
  • 项目排期【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目项目组共有N个开发人员,项目经理接到了M个独立的需求,每个需求的工作量不同,且每个需求只能由一个开发人员独立完成,不能多人合作。假定各个需求直接无任何先后依赖关系,请设计算法帮助项目经理进行工作安排,使整个项目能用最少的时间交付。输入描述:第一行输入为M个需......