思路
首先想一下小凯的疑惑是怎么推出来的。因为互质,那么有一个很明显的性质就是互不相同。一个简单的证明:如果存在使得,那么有。因为,与互质,因此同余式不成立。
自然数对取模只有种取值,填补了最后一个取值(记为),那么小于且对取模为的数字都不能凑出来,其中最大的值为。
现在回到这个题,已经知道第一大的凑不出来的数是了,考虑怎么找第二大的。首先可以去找最后一个没有被填补的空档,也就是。还有一种可能是与当前数字模同余的最大的数字。在二者中取最大值就是第二大的。这样是不会漏下数的,因为其他的数字都被以下的数字填满了。
如果是不能被凑出来的,那么和都不能被凑出来,维护一下已经对前面第几大的数字减过和了,每次在其中选最大值。
这样会不会出现同一个数字(比如和)多次出现的情况呢?实际上是会的,但是同一个数字如果出现多次,必定是同时出现的。因为如果分开出现,那么较小的那个肯定不会再增加回来。
代码
#include<bits/stdc++.h>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define bl(u,i) for(int i=head[u];i;i=e[i].nxt)
#define en puts("")
#define LLM LONG_LONG_MAX
#define LLm LONG_LONG_MIN
#define pii pair<ll,ll>
typedef long long ll;
typedef double db;
using namespace std;
const ll INF=0x3f3f3f3f;
void read() {}
void OP() {}
void op() {}
template <typename T, typename... T2>
inline void read(T &_, T2 &... oth)
{
int __=0;
_=0;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
__=1;
ch=getchar();
}
while(isdigit(ch))
{
_=_*10+ch-48;
ch=getchar();
}
_=__?-_:_;
read(oth...);
}
template <typename T>
void Out(T _)
{
if(_<0)
{
putchar('-');
_=-_;
}
if(_>=10)
Out(_/10);
putchar(_%10+'0');
}
template <typename T, typename... T2>
inline void OP(T _, T2... oth)
{
Out(_);
putchar('\n');
OP(oth...);
}
template <typename T, typename... T2>
inline void op(T _, T2... oth)
{
Out(_);
putchar(' ');
op(oth...);
}
/*#################################*/
const ll N=1e7+10;
ll a,b,k;
ll dp[N];
int main()
{
read(a,b,k);
dp[1]=a*b-a-b;
ll x=1,y=1;
rep(i,2,k)
{
dp[i]=max(dp[x]-a,dp[y]-b);
if(dp[i]==dp[x]-a)
++x;
if(dp[i]==dp[y]-b)
++y;
}
OP(dp[k]);
}