codeforces D. Multiplication Table 二分答案

本文介绍了一种通过二分查找解决寻找n*m乘法表中第K大数的方法。利用二分查找的特性,确定目标数值范围,并通过逐行检查找到满足条件的数值。文章详细解释了算法思路和实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D. Multiplication Table
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Bizon the Champion isn't just charming, he also is very smart.

While some of us were learning the multiplication table, Bizon the Champion had fun in his own manner. Bizon the Champion painted an n × m multiplication table, where the element on the intersection of the i-th row and j-th column equals i·j (the rows and columns of the table are numbered starting from 1). Then he was asked: what number in the table is the k-th largest number? Bizon the Champion always answered correctly and immediately. Can you repeat his success?

Consider the given multiplication table. If you write out all n·m numbers from the table in the non-decreasing order, then the k-th number you write out is called the k-th largest number.

Input

The single line contains integers nm and k (1 ≤ n, m ≤ 5·105; 1 ≤ k ≤ n·m).

Output

Print the k-th largest number in a n × m multiplication table.

Examples
input
2 2 2
output
2
input
2 3 4
output
3
input
1 10 5
output
5
Note

2 × 3 multiplication table looks like this:

1 2 3
2 4 6


题意: 有一个n*m的table, 第i行j列的数字是i*j, 让你求这个表中第k大的数.


分析: 开始知道使用二分, 然而一直不知道怎么二分. 后来看官方题解才知道..

我们可以二分第k大的数, 然后判断是不是成立, 第k大的数有一个特点, 就是比它小的数一定小于k个, 当比它小的数大于等于k个的时候, 一定不是第k大的数, 有了这个单调性, 我们就可以进行二分了. 二分l=1, r=n*m, mid = l+r>>1;

检查的时候从每一行开始, 求小于mid的数目((x-1)/row), 把这些数目相加,检查是不是小于k;

但是有一点值得注意, 就是我们二分得到的答案是不是一定存在于n*m的表中呢? 比如2*3的表, 5 就不会在表中.

由于我们二分得到的是满足情况的最大值. 如果有一个不在表中, 但是满足比它小的数小于k, 那么他后面一定有一个数满足在表中, 同时满足比它小的数小于k, 再大一些的数就不满足条件了.

#include<bits/stdc++.h>

#define inf 0x3f3f3f3f
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;

const int N=100010,MOD=1e9+7;
ll n,m,k;
ll check(ll x )
{
    ll sum=0;
    for(int i=1;i<=n;i++){
        sum += min(m,(x-1)/i);
    }
    return sum;
}
int main()
{

    cin>>n>>m>>k;
    ll l=1,r=n*m,ret;
    while(l<=r)
    {
        ll mid=l+r>>1;
        if(check(mid) < k){
            l=mid+1;
            ret=mid;
        }
        else r=mid-1;
    }
    cout<<ret<<endl;
    return 0;
}





local ar_AKM_DP28 = 5 local ar_BERYL = 4 local ar_G36C = nil local ar_K2 = nil local ar_M16A4_MUTANT = nil local ar_M416 = nil local ar_QBZ = nil local ar_SCAR = nil local lmg_MG3 = nil local smg_BIZON = nil local smg_MP5K = nil local smg_TOMMY = nil local smg_UMP = nil local smg_UZI = nil local smg_VECTOR = nil local dmr_VINTOREZ = nil local dmr_MK12 = nil local dmr_UNIVERSAL = nil local air_AUG = nil local air_GROZA = nil local air_M249 = nil local air_MK14 = nil local air_P90 = nil local click_protection = false local sens_reduction = false local alt_key = "p" local scope_pattern = "capslock" local blink = "capslock" function IsLKeyNotPressed() return not IsMouseButtonPressed(1) end function IsRKeyNotPressed() return not IsMouseButtonPressed(click_key) end local switching = 0 local pattern = falseB function OnEvent(event, arg) if sens_reduction == true then MultiSens = 2 else MultiSens = 1 end if click_protection == true then click_key = 3 else click_key = 1 end if (event == "MOUSE_BUTTON_PRESSED" and arg == ar_AKM_DP28) or (event == "G_PRESSED" and arg == ar_AKM_DP28_KBD) then pattern = not pattern switching = arg if (pattern == false) then OutputLogMessage("OFF-Macro\n") if not IsKeyLockOn(blink) then PressAndReleaseKey(blink) end PressAndReleaseKey(blink) else OutputLogMessage("RedMacro-ar_AKM_DP28-ON\n") if not IsKeyLockOn(blink) then end PressAndReleaseKey(blink) Sleep(300) PressAndReleaseKey(blink) EnablePrimaryMouseButtonEvents(true) end elseif (event == "MOUSE_BUTTON_PRESSED" and arg == ar_BERYL) or (event == "G_PRESSED" and arg == ar_BERYL_KBD) then pattern = not pattern switching = arg if (pattern == false) then OutputLogMessage("OFF-Macro\n") if not IsKeyLockOn(blink) then PressAndReleaseKey(blink) end PressAndReleaseKey(blink) else OutputLogMessage("RedMacro-ar_BERYL-ON\n") if
最新发布
04-02
<think>好的,我需要帮助改进和调试一个涉及多个武器绑定、按键切换和鼠标事件处理的Lua宏脚本。首先,我得理清楚用户的具体需求和遇到的问题。用户提到的脚本可能用于游戏中的快速切换武器,同时处理鼠标点击事件,可能还涉及按键状态的管理。 首先,我应该考虑Lua脚本的结构。可能的问题点包括:变量作用域、事件处理的顺序、条件判断的逻辑错误,或者资源竞争导致的状态不一致。比如,多个武器绑定可能需要不同的按键触发,而切换时如果逻辑不当,可能导致按键冲突或状态未正确更新。 接下来,调试方法。用户可能需要使用打印语句输出变量状态,或者利用调试工具逐步执行。例如,在关键节点添加print语句,查看变量如当前武器、按键状态是否按预期变化。此外,检查是否有全局变量被意外修改,导致状态混乱。 然后,优化代码结构。将不同功能模块化,比如武器切换、鼠标事件处理、按键检测分开处理,使用函数封装,提高可读性和维护性。可能还需要使用状态机来管理不同的武器状态,确保切换逻辑清晰。 关于鼠标事件处理,可能需要考虑鼠标按下和释放的事件顺序,避免重复触发或未及时释放导致的错误。例如,如果在按下鼠标左键时切换武器,可能需要确保当前攻击动作完成后再切换,否则可能出现动画或逻辑错误。 另外,用户提到的引用[3]关于快捷键冲突的问题,需要检查脚本中的快捷键设置是否与其他软件或系统快捷键冲突,导致脚本无法正常触发。例如,ctrl+shift+H是否已被其他程序占用,需要更改脚本的快捷键组合。 可能还需要处理多线程或异步事件的问题,如果脚本同时处理多个按键和鼠标事件,是否有适当的锁或同步机制,避免竞态条件。例如,在切换武器时,如果同时检测到鼠标点击,可能导致状态不一致。 最后,代码风格和格式化,引用[1]提到使用Ctrl + Alt + Enter重新格式化脚本,虽然针对C#,但Lua也需要保持一致的缩进和结构,使用工具如LuaFormatter来提高代码可读性,减少语法错误。 总结,用户的问题可能集中在脚本逻辑错误、事件处理顺序、状态管理和快捷键冲突等方面。需要逐步排查,模块化处理,并利用调试工具和打印语句来定位问题。</think>以下是关于Lua宏脚本改进与调试的分步指南: ### 一、基础调试方法 1. **日志输出** 在关键逻辑节点插入`print`语句,输出变量状态: ```lua print("当前武器状态:"..tostring(currentWeapon)) print("鼠标左键状态:"..tostring(isMouseDown)) ``` 2. **作用域检查** 使用`local`关键字限定变量作用域,避免全局污染: ```lua local function switchWeapon() local targetWeapon = GetNextWeapon() -- 明确作用域 end ``` 3. **事件顺序验证** 通过时间戳记录事件触发顺序: ```lua OnMouseDown = function() lastActionTime = os.time() end ``` ### 二、武器绑定与切换优化 1. **状态机实现** 使用状态模式管理武器切换逻辑: ```lua weaponStates = { primary = {fireRate = 0.5, ammo = 30}, secondary = {fireRate = 1.2, ammo = 8} } function SwitchState(newState) currentState = weaponStates[newState] UpdateHUD() -- 同步更新界面 end ``` 2. **按键防抖处理** 添加延迟检测防止快速切换导致的异常: ```lua local lastSwitchTime = 0 function OnKeyPress() if os.clock() - lastSwitchTime > 0.3 then -- 300ms冷却 PerformSwitch() lastSwitchTime = os.clock() end end ``` ### 三、鼠标事件处理 1. **事件优先级设置** 通过标志位控制事件处理流程: ```lua local isReloading = false function OnFire() if not isReloading then StartFireAnimation() else QueueFireAction() -- 加入待处理队列 end end ``` 2. **连发控制** 使用协程实现自动射击节奏控制: ```lua function AutoFire() CreateCoroutine(function() while mouseDown do FireProjectile() Sleep(currentState.fireRate) -- 按武器射速等待 end end) end ``` ### 四、快捷键冲突排查 1. **输入监听分离** 为不同设备事件分配独立处理通道: ```lua RegisterKeyEvent("WeaponSwitch", "F", function() -- 处理逻辑 end) RegisterMouseEvent("QuickMelee", "Button4", function() -- 近战攻击 end) ``` 2. **热键配置检查** 参考引用[3]的快捷键配置建议,确保: ```lua -- 检查配置文件是否存在冲突 if IsKeyBound("Ctrl+Shift+H") then RebindKey("WeaponMenu", "Ctrl+Alt+H") -- 修改绑定 end ``` ### 五、性能优化 1. **内存管理** 及时释放未使用的资源: ```lua function UnloadWeapon() ReleaseTexture(currentWeapon.model) CollectGarbage("step") -- 分步回收内存 end ``` 2. **事件代理优化** 使用弱引用表防止内存泄漏: ```lua local eventListeners = setmetatable({}, {__mode = "v"}) ``` ### 六、调试工具推荐 1. **使用Lua IDE** 如ZeroBrane Studio支持断点调试和变量监控 2. **内置调试库** 通过`debug.traceback()`获取调用堆栈: ```lua function ErrorHandler(err) Log(debug.traceback("Error: "..err)) end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值