给定 \(a,b,L,R\),找到最小的 \(p\geq 0\),使得 \(pa\bmod b\in[L,R]\)。
设 \(qb\leq pa<(q+1)b\)。
等价于找到最小的 \(q\geq 0\),使得存在 \(qb\leq pa<(q+1)b\) 满足 \(pa\bmod b\in [L,R]\),即存在 \(p\) 满足 \(pa-qb\in[L,R]\)。
设 \(b=ka+r\),转化为找到最小的 \(q\geq 0\),使得存在 \(p\) 满足 \((p-qk)a-qr\in [L,R]\)。
注意到 \(q\) 确定后,\(p\) 的取值能使得 \((p-qk)a-qr\) 取到模 \(a\) 同余于 \(-qr\) 的任何数,于是,我们只需存在 \(x\in [L,R]\) 使得 \(-qr\equiv x\pmod a\) 即可。
若存在 \(x\in [L,R]\) 使得 \(x\) 是 \(a\) 的倍数,则 \(q=0\);否则,我们需找到最小的 \(q\geq 0\) 使得 \(qr\bmod a\in[-R\bmod a,-L\bmod a]\)。
这就递归到了子问题。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int mod(int x,int b)
{
return (x%b+b)%b;
}
int calc(int a,int b,int L,int R)//find min p and exist x in [L,R] that pa = x (mod b)
{
if(R-L+1>=b) return 0;
L=mod(L,b),R=mod(R,b);
if(L>R) return 0;
int k=b/a,r=b-k*a;
int q=calc(r,a,-R,-L);
return (q*b+L+a-1)/a;
}
int solve(int a,int b,int V,int M)
{
int p=calc(a,b,M-a+1-V,b-1-V);
int q=(V+p*a)/b;
assert(V+p*a-q*b+a>M);
return p+q;
}
signed main()
{
int T; cin>>T;
while(T--)
{
int A,B,V,M;
cin>>A>>B>>V>>M;
if(A+B<=M+1)
{
printf("%lld\n",M+1);
continue;
}
printf("%lld\n",solve(A,B,V,M)+solve(A,B,M-V,M)+1);
}
return 0;
}
原文地址:http://www.cnblogs.com/ez-lcw/p/16837096.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性