首页 > 其他分享 >2024ICPC武汉邀请赛-G.Pack-数论分块、整除运算相关的不等式

2024ICPC武汉邀请赛-G.Pack-数论分块、整除运算相关的不等式

时间:2024-05-07 21:22:58浏览次数:17  
标签:lfloor geq frac 不等式 分块 2024ICPC rfloor leq Pack

link:https://codeforces.com/gym/105143
Group contests:https://codeforces.com/group/DWEH34LQgT/contest/521901
题意:有 \(n\) 件 \(A\) 物品, \(m\) 件 \(B\) 物品,两种物品价值分别是 \(a,b\),若干件 \(A\) 和若干件 \(B\) 可以打包成一个商品,打包尽可能多的商品的情况下让剩余的 \(A,B\) 物品件数和最小,同时商品价值恰好是 \(k\)。


虽然感觉是比较基础的题…但是写的时候并不是那么熟练,一些细节的地方处理了一小会儿,感觉还是有必要进行一个复盘。

题意翻译过来就是求 $$n+m-\min(\lfloor\frac{n}{x}\rfloor,\lfloor\frac{m}{y}\rfloor)\times(x+y)$$
的最小值,\(n+m\) 固定,也就是最大化后面的部分

注意到 \(n,m\) 对称,而且 \(\lfloor n/x\rfloor\) 只有 \(\Theta(\sqrt n)\) 种取值,强制让某个数的块小(例如 \(x\) ),就变成了如下问题:

  • 找到每个 \(\lfloor n/x\rfloor=v\) 的块,强制让 \(v=\lfloor n/x\rfloor \leq \lfloor m/y\rfloor\)
  • 对每个块 \(v\),可以确定 \(x\) 的一个取值范围。
  • 对不定方程 \(ax+by=k\) ,先求得一组 \(ax_0+by_0=\gcd(a,b)\equiv d\) 的特解,将特解乘上 \(k/d\) 得到右侧是 \(k\) 的特解,写出其通解为

\[\begin{aligned}x&=x_0+t\cdot \frac{b}{d}\\ y&=y_0-t\cdot \frac{a}{d}\end{aligned}\]

  • 要求满足不等式:
    • 1、\(x\geq 0\),\(\lfloor n/x\rfloor=v\).
    • 2、\(y\geq 0\)
    • 3、\(v \leq \lfloor m/y\rfloor\).
  • 分别求解:
    • 1、除法分块得到一个 \(x\) 的范围 \([L,R]\),所以\(L\leq x_0+tb/d\leq R\),$$\lceil(L-x_0)\frac{d}{b} \rceil \leq t\leq \lfloor (R-x_0)\frac{d}{b}\rfloor$$
    • 2、\(y=y_0-t\cdot a/d\geq 0\),\(t\leq \lfloor \frac{y_0\cdot d}{a}\rfloor\).
    • 3、这里我第一次写的时候想的是,\(\lfloor m/y\rfloor\) 也是 \(\Theta(\sqrt m)\) 种取值,预处理出每一段 \(y\) 的范围,双指针扫描。但后面仔细想想,这里的 \(y\) 肯定是可以直接求解的(见后文)。
  • 可以得到一个 \(t\) 的取值范围 \(t\in [l_t,r_t]\),\(x+y=(x_0+y_0)\cdot \frac{k}{d} +\frac{t}{d}(b-a)\),很明显关于 \(t\) 单调,在端点取值即可

除法分块相关的不等式

  • \(\lfloor n/x\rfloor\) 只有 \(O(\sqrt n )\) 种取值,并且在 \(x\leq \sqrt n\) 时,\(x\) 每次变化都导致 \(\lfloor n/x\rfloor\) 不同;而在 \(x\geq \sqrt n\) 时,\(x\) 改变 \(1\) 至多导致 \(\lfloor n/x\rfloor\) 变化 \(1\).

一些相关的不等式:

  • 1、对于不等式 \(\lfloor n/x\rfloor\geq v\),有 \(n/x\geq \lfloor n/x\rfloor\geq v\),得到 \(x\leq \lfloor n/v\rfloor\),可以得到一个 \(x\) 的上界,同时代入 \(\lfloor n/v\rfloor\),会有 $$\lfloor \frac{n}{\lfloor n/v\rfloor}\rfloor\geq \lfloor\frac{n}{n/v}\rfloor=\lfloor v\rfloor=v$$同时 $$\lfloor\frac{n}{\lfloor n/v\rfloor +1}\rfloor>\lfloor \frac{n}{n/v}\rfloor=v$$
    因此 \(\lfloor n/x\rfloor\geq v\) 的解恰是 \(x\leq \lfloor n/v\rfloor\).

  • 2、对于不等式 \(\lfloor n/x\rfloor\leq v\),直接取 \(x\geq \lfloor n/v\rfloor\) 明显是不对的,例如 \(n=10,v=2\),当 \(x\geq 4\) 时 \(\lfloor 10/x\rfloor \leq 2\),而 \(\lfloor 10/2\rfloor=5\)。应该考虑 $$\frac{n}{x}-1<\lfloor \frac{n}{x}\rfloor \leq v$$
    得到 $$\begin{aligned}\frac{n}{x}<v+1\ \Leftrightarrow\ x>\frac{n}{v+1}\ \Leftrightarrow\ x\geq \lfloor\frac{n}{v+1}\rfloor +1\end{aligned}$$
    这是一个下界,同时 $$\lfloor \frac{n}{\lfloor n/(v+1)\rfloor}\rfloor\geq \lfloor \frac{n}{n/(v+1)}\rfloor=v+1$$
    因此对不等式 \(\lfloor n/x\rfloor \leq v\) 的解应该恰是 \(\lfloor \frac{n}{v+1}\rfloor +1\),这是比较不同的地方。

题目代码

(写的还是双指针的写法)

#include<bits/stdc++.h>
#define endl '\n'
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
const ll INF=2e18;
int exgcd(ll &x,ll &y,int a,int b){
    if(!b){
        x=1;y=0;
        return a;
    }
    int d=exgcd(x,y,b,a%b);
    ll tx=x,ty=y;
    x=ty;y=tx-(a/b)*ty;
    return d;
}
int work(int n,int m,int a,int b,int k){
    //adjust
    ll x0,y0,d=exgcd(x0,y0,a,b);
    x0=x0*k/d;y0=y0*k/d;
    ll tx=(x0%(b/d)+(b/d))%(b/d),dd=(x0-tx)/(b/d);
    x0=x0-dd*(b/d);y0=y0+dd*(a/d);
    //solve
    ll ans=0;
    vector<int> seg;
    for(int y=1,pos;y<=m;y=pos+1){
        pos=min(m,m/(m/y));
        seg.push_back(pos);
    }
    int j=0;
    for(int x=1,R;x<=n;x=R+1){
        int L=x;
        R=min(n,n/(n/x));
        int lt=ceil((double)(L-x0)/(b/d));
        int rt=floor((double)(R-x0)/(b/d));

        while(j+1<seg.size()&&(m/seg[j+1])>=(n/x))j++;
        if(m/seg[j]<(n/x))continue;

        lt=max(lt,(int)ceil((double)(y0-seg[j])*d/a));
        rt=min(rt,(int)floor((double)y0*d/a));
        
        if(lt>rt)continue;
        ans=max(ans,(ll)(n/x)*(x0+y0+(ll)(b-a)/d*lt));
        ans=max(ans,(ll)(n/x)*(x0+y0+(ll)(b-a)/d*rt));
    }
    return ans;
}
int main(){
    fastio;
    int tc;cin>>tc;
    while(tc--){
        int n,m,a,b,k;
        cin>>n>>m>>a>>b>>k;
        cout<<n+m-max(work(n,m,a,b,k),work(m,n,b,a,k))<<endl;
    }
    return 0;
}

标签:lfloor,geq,frac,不等式,分块,2024ICPC,rfloor,leq,Pack
From: https://www.cnblogs.com/yoshinow2001/p/18178417

相关文章

  • CMake中里的find_package与find_library有什么区别?
    在CMake中,find_package和find_library都是用来找到和链接库的方法,但它们的用法和适用场景略有不同。find_package主要用于寻找具有CMake配置文件的库,这些库通常遵循CMake的规范,提供了用于导入目标、库路径、头文件路径等的配置文件。这使得使用find_package更加简洁,只需指定需......
  • 【cmake】find_package设置查找路径
     1.find_package的作用与实例用来查找第三方依赖包的.cmake文件,并根据.cmake文件生成依赖包的头文件目录和库文件路径等;CMakeLists.txt实例find_package(ProtobufREQUIRED)include_directories(${PROTOBUF_INCLUDE_DIR})add_executable(mainsrc/main.cpp)target......
  • Only a type can be imported. XXX resolves to a package
    在编写jsp页面是,导入需要的包,运行时报错main.jsp<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><%@pageimport="java.util.List"%><%@pageimport="com.beans.E......
  • Android开发 Jetpack Compose Canvas
    版权声明本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/17657716.html本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。前言  此篇博客讲解Canvas的使用 画线正常的线条效果图......
  • ORA-04063: Package Body “SYS.DBMS_CUBE_EXP” While Expdp
    1.场景数据库版本:11.2.0.4当执行@?/rdbms/admin/awrextr.sql进行awr性能分析数据导出时,报错:ORA-20115:datapumpexportencounterederror:ORA-39127:unexpectederrorfromcalltoexport_string:=SYS.DBMS_CUBE_EXP.INSTANCE_EXTENDED_INFO_EXP('AW$EXPRESS','SYS',......
  • 分块 - 树分块
    分块-树分块LuoguP3203[HNOI2010]弹飞绵羊经典的\(LCT\)板子题,十分滴规范,但我们今天不讲\(LCT\)我们用树分块这个俎法哈,又短又快的咩(好像不是很快哈,同学们要认真学习哈我们把一个点能到的点当成它的老子,那\(N+1\)就是根的咩显然它的编号越跳越大撒,我们就......
  • [分块] [Luogu AT_joisc2014_c] 历史研究
    题目描述IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记。JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件。日记中记录了连续\(N\)天发生的事件,大约每天发生一件。事件有种类之分。第\(i\)天发生的......
  • 分块=-=优雅的暴力=-=中位数模版
    #include<bits/stdc++.h>//#defineintlonglong#definelllonglong#definefd(i,a,b)for(registerinti=a;i<=b;i=-~i)#definebd(i,a,b)for(registerinti=a;i>=b;i=~-i)usingnamespacestd;constintN=1e5+509,M=509,MOD=10007;intn,siz,id;......
  • x32dbg 手动脱NsPack 壳
    记一下步骤 文件名字(太长遂改):1111.exe文件来源:攻防世界Reverse三星题,crackme工具选择:下载的文件出现病毒报错,一开始是用OD脱壳,但是修复表的时候,无法运行程序,所以改用x64脱壳方法:ESP 在PE中 在die中发现存在NsPack壳丢到x32dbg中找到程序代码入口 F8到call指令......
  • webpack
    vue是基于es6的开发的let是局部变量什么是Webpack本质上,webpack是一个现代JavaScript应用程序的静态模块打包器(modulebundler)。当webpack处理应用程序时,它会递归地构建一个依赖关系图(dependencygraph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个b......