P3951 Oscar doubts


题面:https://www.luogu.org/problemnew/show/P3951

题目虽然要求的是最大的不能表示为ax+by的形式的数,但我们可以通过这个数+1来求,我们设这个数为n,则有:

n=ax+by (x,y∈N)

我们再考虑n−1可以怎么表示。注意到gcd(a,b)=1,于是我们就可以把n−1中的1也用a,b的线性组合表示。

n−1=ax+by−(ax0+by0)=a(x−x0)+b(y−y0)(这里ax0+by0=1)

由于n−1不能表示为ax+by (x,y∈N)的形式,所以∀(x0,y0),x−x0​<0和y−y0<0中至少有一个成立,即x<x0和y<y0中至少有一个成立。

首先,由ax0+by0=1,x0​和y0必定不能同号。所以,当x0>0时,y0≤0,y−y0​≥y≥0,必须有x−x0<0成立,即有x<x′(x′为最小的非负x0),同理y<y′′(y′′为最小的非负y0)。要注意的是,这里的x′,y′′并不是ax0​+by0​=1的一组解,而是相互独立的x0​最小的非负整数解和y0最小的非负整数解。

因为我们要求的是n的最大值,x,y要尽量大,所以x,y均取最大值,即x=x′−1,y=y′′−1

再将(x′,y′′)代入,即可得到n=a(x′−1)+b(y′′−1),即Ans=a(x′−1)+b(y′′−1)−1

带一个exgcd先解出一组(x0​,y0​),再算出x′,y′′,代入求解即可。

但是这并不是最优解,因为还有一个ab−a−b的神仙式子可以秒掉此题。其实我们可以将之前的式子Ans=a(x′−1)+b(y′′−1)−1继续化简,把x′和y′′给化掉。

因为(x′,y′)和(x′′,y′′)为不定方程ax0​+by0​=1的两组不同的解,所以我们就想办法把这两组解联系在一起。

注意到有x′′=x′+tb,y′′=y′−ta(t∈Z)

因为(x′′,y′′)为y0​最小且非负的解,易知x′′最大且非正的x0​。而x′为最小且非负的x0,那么这两组解就是连续的两组解了,也就是说t=−1,于是y′′=y′+a

所以,Ans=ax′−a+by′′−b−1=ax′+by′+ab−a−b−1=ab−a−b

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<queue>
using namespace std;
long long a,b;
int main(){
    scanf("%lld%lld",&a,&b);
    printf("%lld",a*b-a-b);
    return 0;
}

Guess you like

Origin www.cnblogs.com/ukcxrtjr/p/11184544.html