首页 > 其他分享 >Atcoder ABC389E Square Price 题解 [ 绿 ] [ 二分 ] [ 贪心 ]

Atcoder ABC389E Square Price 题解 [ 绿 ] [ 二分 ] [ 贪心 ]

时间:2025-01-18 23:10:17浏览次数:1  
标签:__ Atcoder Square 题解 times 出题 res int128 mx

Square Price:垃圾卡精度,垃圾卡精度,垃圾卡精度,傻逼出题人,傻逼出题人,傻逼出题人,傻逼出题人,傻逼出题人,傻逼出题人,傻逼出题人。

ll__int128WA*22,改 __int128 直接 AC 了,难评。

抛开卡精度这题还是挺好的。

暴力

先考虑暴力思路,显然暴力应该这么打:把所有物品全丢进优先队列里,每次选出价值最小的物品,把多选择一个的物品的价值与当前数量的物品价值做差,丢进优先队列。一直执行直到不能选为止。

显然可以构造全 \(1\) 的数据来把它卡爆,不能过。

正解

考虑优化暴力的过程,不难发现,我们最后取出的结果,代价一定小于等于某一个值。而每个元素选的越多,每一个的代价就越多,因此我们可以二分出最后选出的最大代价,设为 \(mx\)。假设当前在计算第 \(i\) 个元素在此限制下最多能选 \(k\) 个该元素,则可以得到下列不等式:

\[p_i\times(k^2-(k-1)^2)\le mx \]

\[p_i\times(2k-1)\times 1 \le mx \]

\[2k-1 \le \frac{mx}{p_i} \]

\[k \le \frac{mx}{2\times p_i}+\frac{1}{2} \]

因此,我们就可以求出 \(k\) 了,之后在 check 时将当前答案加上 \(k^2\times p_i\),最后看答案是否小于等于 \(m\) 即可。

最后统计答案的时候,因为二分时默认所有选的代价都小于等于 \(mx\),那么如果 \(mx\) 后面的还有剩余,就还要加上这一部分的答案。

时间复杂度 \(O(n \log V)\)。

注意精度问题,要开 __int128long double,二分边界记得开大!

总结

不论精度问题的话,这题还挺巧妙的。这题能用二分代替优先队列的关键就在于下列几点:

  • 是取所有价值中的前 \(x\) 小值,具有单调性。
  • 单个元素的贡献能被快速计算。
  • 单个元素的代价具有单调性。

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
using pl=pair<ll,pair<ll,pair<ll,ll> > >;
ll n,m,p[200005],res=0;
bool check(ll mx)
{
    res=0;
    __int128 now=0;
    for(int i=1;i<=n;i++)
    {
        __int128 k=max(__int128(0),__int128(floor(ldb((ldb(1.0*mx)/ldb(p[i])+1.0))/ldb(2.0))));
        now+=k*k*p[i];
        if(now>m)return 0;
        res=res+k;
    }
    return 1;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>p[i];
    ll l=0,r=1e15,mid;
    while(l<r)
    {
        mid=(l+r+1)>>1;
        if(check(mid))l=mid;
        else r=mid-1;
    }
    res=0;
    __int128 now=0;
    for(int i=1;i<=n;i++)
    {
        ll k=max(__int128(0),__int128(floor(ldb((ldb(1.0*l)/ldb(p[i])+1.0))/ldb(2.0))));
        now+=__int128(k)*__int128(k)*__int128(p[i]);
        res+=k;
    }
    for(int i=1;i<=n;i++)
    {
        __int128 kx=max(__int128(0),__int128(floor(ldb((ldb(1.0*l)/ldb(p[i])+1.0))/ldb(2.0))));
        __int128 ky=max(__int128(0),__int128(floor(ldb((ldb(1.0*(l+1))/ldb(p[i])+1.0))/ldb(2.0))));
        __int128 cst=__int128(ky)*__int128(ky)*__int128(p[i]),oricst=__int128(kx)*__int128(kx)*__int128(p[i]);
        if(kx!=ky&&now-oricst+cst<=m)
        {
            now=now-oricst+cst;
            res++;
        }
    }    
    cout<<res;
    return 0;
}

标签:__,Atcoder,Square,题解,times,出题,res,int128,mx
From: https://www.cnblogs.com/zhr0102/p/18679014

相关文章

  • 【鱼皮大佬API开放平台项目】Spring Cloud Gateway HTTPS 配置问题解决方案总结
    问题背景项目架构为前后端分离的微服务架构:前端部署在8000端口API网关部署在9000端口后端服务包括:api-backend(9001端口)api-interface(9002端口)初始状态:前端已配置HTTPS(端口8000)后端服务未配置HTTPS通过Nginx进行反向代理遇到的问题第一阶段:400Ba......
  • uniapp获取元素高度不准确问题解决
    uniapp通过boundingClientRect获取的元素高度和实际高度差了不少,下面是复现和解决过程:我的代码: 得到的结果: 高度只有105用工具量一下: 实际有240px,遂gpt问下: 注意到了缩放比这个之前没想到的点,往下面看gpt更多的回复内容: 先获取系统缩放比,再乘以拿到的......
  • Toyota Programming Contest 2025(AtCoder Beginner Contest 389)
    A-9x9题意:给你一个长度为\(3\)的乘法式,求答案。直接求即可。点击查看代码voidsolve(){std::strings;std::cin>>s;std::cout<<(s[0]-'0')*(s[2]-'0')<<"\n";}B-tcaF题意:求一个\(n\),使得\(n!=x\)。模拟即可。点......
  • [BZOJ3451] Normal 题解
    这题分三步:葺网(期望)、淀粉质(点分治)、蓉翅(容斥),再佐以芬芳团(FFT),一道巨难无比的luogu黑题就诞生了。期望先考虑在淀粉树上,\(i\)点在\(j\)点的子树里的概率。实际上这个问题的每种情况相当于是\(n\)个点的各种排列方式。这也就相当于,我们在选择\(j\)点之前,没有选择路径\((......
  • PKUWC 2025 题解
    本人太菜,实在不会T3,所以只有T1,T2的题解。注:考场上只做出来了Day1T1,其他题参考了其他人的题解。Day1T1题面有\(a\)个有电的电池和\(b\)个没电的电池,每次只能选择两个电池放进手电筒,只有这两个电池全有电才能让手电筒启动。问最坏情况下最少可以让手电筒启动的尝试次......
  • THUWC2025题解
    Day1T1构造一个排列,使满足最多的形如\([l,r]\)内单调递增/减。一个简单的线段树优化DP,设状态\(f_{i,0/1}\)即可转移,\(O(n\logn)\)。T2支持往集合中加三维带权点,查询集合中没有任何一维与给出点对应维度相等的最大点权。唐题。一种暴力的想法是三维数点之类的,不太能......
  • PKUWC2025部分题解
    Day1A注意到,原题等价于构造一个\(a+b\)个点的完全图,使最大独立集\(<a\),且边数最小。很难发现,图必然被划分成\(a-1\)个完全图。据此DP或令\(a-1\)个图点数平均。CDAG上考虑暴力。设\(f_{u,i}\)表示第\(i\)轮在\(u\)是否先手必胜。转移枚举相邻点就好,\(\large......
  • [ZJOI2014] 力 题解
    容易发现:\[E_i=\sum_{j=1}^{i-1}\frac{q_j}{(i-j)^2}-\sum_{j=i+1}^n\frac{q_j}{(i-j)^2}\]不妨设\(a_i=q_i,b_i=\dfrac1{i^2}\):\[E_i=\sum_{j=1}^{i-1}a_jb_{i-j}-\sum_{j=1}^{n-i}a_jb_{j-i}\]发现前半部分就是多项式乘法,后半部分与[BZOJ2194]一致。直接FFT干过去即可......
  • 线性dp+背包问题题解
    线性dp理解递推/记忆化搜索,有很多种理解方式递归重叠子问题的记忆化搜索:像这里例如\(f[3]\)可以通过一次计算得到,保存答案,下一次直接调用即可,省去很多复杂度我们从此引出dp第一个性质:最优子结构大问题的最优解包含小问题的最优解,并且小问题的最优解可以推导出大问题的最优......
  • P1076 [NOIP2012 普及组] 寻宝 题解
    题目传送锚点在博客园食用更佳本题纯纯模拟题,甚至连大模拟都算不上。别问我是怎么知道的,问就是看那恶心的题目描述、标签和题目难度仅为黄知道的。好了,上思路。既然是大模拟,那就按照题目描述给的思路来,一层一层往上爬呗。一下是两点注意事项:输入时,可以考虑用二维数组或结构......