[ARC127F] ±AB
statement
有一个数 \(V\),你可以进行若干次 \(+A,-A,+B,-B\) 操作,需要保证任意时刻 \(0\leq V\leq M\),求可以变成那些数字。
solution
- \(A+B-1\leq M\)
引理一:若 \(x=V+pA+qB\in [0,M]\) ,则 \(V\) 可以变成 \(x\) 。
若 \(p,q\) 同号,显然成立。
若不同号,不妨设 \(p>0,q<0\),那么我们可以一直减 \(B\) 直到达到上限或者不能减了,若达到上限,此时一定可以加 \(p\) 次 \(A\),若不能减了,当前的数字 \(v<B\),那么一定可以执行一次加 \(A\),因为 \(v+A\leq A+B-1\leq M\),因此我们就不停地 \(-B,+A\) 直到合法即可。
因为 \(\gcd(A,B)=1\),所以根据裴蜀定理,\(x\) 可以取遍 \([0,M]\) 。
- \(A+B-1>M\)
不妨令 \(V=V\bmod A\),显然这和原问题等价。
显然第一步不能选择 \(-A\),且因为 \(A<B\),第一步也不能选择 \(-B\) 。
不妨设第一次选择了 \(+A\),那么接下来不能选择 \(-A\),因为重复了,也不能 \(+B\),因为 \(A+B-1>M\)。那么只能在 \(+A,-B\) 中选一个,并且显然两个不能同时选,因此对于每个数,都只有唯一的出边,另一种走法 \(+B,-A\) 同理。
引理二:转移图无环
不妨设最小环走了 \(x\) 次 \(+A\),\(y\) 次 \(-B\),则 \(Ax=By\),因为 \(\gcd(A,B)=1\),该方程最小正整数解为 \(B,A\)。
但是因为 \(A+B>M+1\),所以环一定重复经过了某些点,与环是最小的矛盾。
引理三:两种走法无交
因为两种走法起点相同,所以若相交,那么一定有环,与上矛盾。
因此可以对两种走法分别计算最远走多少步再加起来就是答案,以 \(+A,-B\) 为例。
不妨设进行了 \(k\) 次 \(+A\),因为走不动了,所以最终的数 \(x\) 一定满足 \(x\in [m-A+1,B-1]\),那么一定进行了 $\lfloor \frac{V+kA}{B} \rfloor $ 次 \(-B\) 。
也就是说,我们要找最小的 \(k\),满足 $(V+kA)\bmod B+A\geq M+1 $ 。
令 \(V0=V\bmod B\),若 \(V0+A>M\),显然此时答案为 $\lfloor \frac{V}{B} \rfloor $ 。
否则:
引理四:\(V0+(kA\bmod B)<B\)
若不然,我们先减去 \(B\),然后 \(+A\),一定合法,矛盾。
因此 \((V+kA)\bmod B=V0+(kA\bmod B)\),转为计算 \(L\leq (kA)\bmod B\leq R\) 的最小的 \(k\) 。
考虑使用类欧求解。
令 \(B=pA+q,t=\lfloor \frac{kA}{B} \rfloor\),那么 \((kA)\bmod B=kA-Bt=kA-(pA+q)t=A(k-tp)-tq\),可以变成 \(tq\bmod A\in [L',R']\),递归计算。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int Euclid(int A,int B,int L,int R)
{
if(A==0) return 0;
A%=B;
if((L-1)/A!=R/A) return (L+A-1)/A;
int t=Euclid(B%A,A,(A-R%A)%A,(A-L%A)%A);
return (1ll*t*B+L+A-1)/A;
}
int walk(int A,int B,int V,int M)
{
int V0=V%M;
if(V0+A>M) return V/B;
int k=Euclid(A,B,M-A-V0+1,B-V0-1);
return k+(V+1ll*A*k)/B;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int A,B,V,M;
scanf("%d %d %d %d",&A,&B,&V,&M);
if(A+B-1<=M)printf("%d\n",M+1);
else printf("%d\n",walk(A,B,V%A,M)+walk(B,A,V%A,M)+1);
}
return 0;
}

浙公网安备 33010602011771号