ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

「codeforces - 1344D」Résumé Review

2022-06-30 08:33:30  阅读:151  来源: 互联网

标签:tmp int sum codeforces mid Delta 1344D ll


link。

有点狗,但还算个好题。

设定 \(f_i(x)=a_ix-x^3\),\(\Delta_i(x)=f_i(x)-f_i(x-1)\),可以洞察到 \(\Delta_i(x)\) 在正自然数中是递减的。那么我们就可以贪心了。贪心时我们维护一个向量 \((b_1,\dots,b_n)\),分别表示 \(\Delta_i(b_i)\),初始全为零。放进优先队列里面,每次取一个出来(记为 \(\textit{id}\))将 \(b_{\textit{id}}\) 增量 \(1\),再放入优先队列里面。最终我们得到的即是使得答案最优的向量。

复杂度不可接受,我们优化的方向应当是提高生产力,怎样批量决定该做哪些。考虑二分一个标准线 \(t\),如果存在向量满足 \(\sum b_i\leqslant k\),且我们只做了 \(\Delta_i(b_i)\geqslant t\) 的函数,就行了。设 \(f(t)\) 为达到标准线的函数个数,最后我们得到的 \(t\) 满足 \(f(t)\leqslant k<f(t+1)\)。

然后通过调整可得到答案。

#include <bits/stdc++.h>
using namespace std;
using ll = __int128;
#define int ll
int n, k, a[100100], b[100100];
ll of(ll x, ll a) {
    return a*x-x*x*x;
}
ll df(ll x, ll i) {
    return of(x, a[i])-of(x-1, a[i]);
}
int f(int i, int stl) {
    int l = 0, r = a[i], mid, res = 0;
    while (l <= r) {
        mid = (l+r)/2;
        if (df(mid, i) >= stl) l = mid+1, res = mid;
        else r = mid-1;
    }
    return res;
}
bool check(ll cur) {
    // @cur stands for the standard line
    ll sm = 0;
    for (int i=1;i<=n;++i) {
        int ret = f(i, cur);
        sm += ret, b[i] = ret;
    }
    return sm <= k;
}
ll bsrh(ll l, ll r) {
    ll mid, res = -1;
    while (l <= r) {
        if(check(mid = (l+r)/2)) r = mid-1, res = mid;
        else l = mid+1;
    }
    return res;
}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    long long tmp;
    cin >> tmp;
    n = tmp;
    cin >> tmp;
    k = tmp;
    for (int i=1;i<=n;++i) {
        cin >> tmp;
        a[i] = tmp;
    }
    int t = bsrh(-9e18, 9e18), sum = 0;
    check(t-1);
    for (int i=1;i<=n;++i) sum += b[i];
    for (int i=1;i<=n;++i) {
        int adj = f(i, t-1)-f(i, t);
        if (sum > k) {
            if (sum-adj <= k) {
                b[i] -= (sum-k);
                break;
            }
            else {
                sum -= adj, b[i] -= adj;
            }
        }
    }
    for (int i=1;i<=n;++i) {
        tmp = b[i];
        cout << tmp << " \n"[i == n];
    }
    return 0;
}

标签:tmp,int,sum,codeforces,mid,Delta,1344D,ll
来源: https://www.cnblogs.com/orchid-any/p/16425543.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有