【ARC127F】±AB
Description
给定长度为 的数轴和起始位置 。另外给定两个互质整数
每次操作可以从当前位置移动到 或者 但是不能超过数轴的边界
求在进行任意多次操作之后的可达点数量
输入文件共 组数据
Solution
首先 时答案是 。注意到 ,将从 走到某个位置 刻画成若干位移的合成,优先使用正位移,正位移无法使用的时候使用负位移即可
对于 的情况,进行完 操作之后只能进行 操作,对于 操作会超界,而 操作不能走到之前没走过的位置。而 操作只能进行其中之一,那么能进行的操作形成了一条链
尝试考察同一条链中是否有重复经过某个点的情况出现,考察 最小 循环里面使用了 次 , 次 ,再根据 得到 ,那么 ,在这个过程中必然经过了重复的点。矛盾
再考察两条链之间是否有除了出发点 之外的交点,这显然没有,否则根据决策唯一性(前驱后继唯一)两条链将成为一条链。
此时两条链的边的数量之和 就是能经过的总点数。
枚举 操作的总次数,两者做法一致,那么以 为例。
枚举 操作的操作数量 , 操作最多可以进行 。那么要求的就是最小的 满足
将其展开可以得到 ,连续不等式首尾均为定值,那么可以将问题抽象成求 表示求最小的 满足
这是常见问题,设 并且设 ,那么进行一些和式变换就可以得到子问题
当然如果区间已经包含 可以直接返回 ,否则可以将 对 取模再递归
得到子问题 的最小值之后可以还原 的最小值
时间复杂度
这是不是类欧几里得呢?
Code
inline int get(int A,int B,int L,int R){
if(!A) return 0;
if((L-1)/A==R/A){
int q=get(B%A,A,(A-R%A)%A,(A-L%A)%A);
return (q*B+L+A-1)/A;
}
return (L+A-1)/A;
}
inline int calc(int A,int B,int V,int M){
int V0=V%B,p=0;
if(V0+A<=M) p=get(A,B,M-V0-(A-1),B-1-V0);
return p+(V+p*A)/B;
}
signed main(){
int T=read();
while(T--){
int A=read(),B=read(),V=read(),M=read();
if(A+B<=M+1){
print(M+1);
continue;
}
print(calc(A,B,V,M)+calc(B,A,V,M)+1);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律