给定 \(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. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性