小L的疑惑 题解

77 阅读2分钟

题目链接

思路

首先想一下小凯的疑惑是怎么推出来的。因为a,ba,b互质,那么有一个很明显的性质就是0×bmoda,,(a1)×bmoda0\times b\mod a,\cdots,(a-1)\times b\mod a互不相同。一个简单的证明:如果存在p,qp,q使得pbmoda==qbmoda(0p<q<a)pb\mod a==qb\mod a(0\leq p<q<a),那么有(qp)b0(moda)(q-p)b\equiv0\pmod a。因为qp<aq-p<abbaa互质,因此同余式不成立。

自然数对aa取模只有aa种取值,(a1)×b(a-1)\times b填补了最后一个取值(记为rr),那么小于(a1)×b(a-1)\times b且对aa取模为rr的数字都不能凑出来,其中最大的值为(a1)×ba=abab(a-1)\times b-a=ab-a-b

现在回到这个题,已经知道第一大的凑不出来的数是ababab-a-b了,考虑怎么找第二大的。首先可以去找最后一个没有被(a2)×b(a-2)\times b填补的空档,也就是ababbab-a-b-b。还有一种可能是与当前数字模aa同余的最大的数字ababaab-a-b-a。在二者中取最大值就是第二大的。这样是不会漏下数的,因为其他的数字都被(a2)×b(a-2)\times b以下的数字填满了。

如果xx是不能被凑出来的,那么xax-axbx-b都不能被凑出来,维护一下已经对前面第几大的数字减过aabb了,每次在其中选最大值。

这样会不会出现同一个数字(比如xabx-a-bxbax-b-a)多次出现的情况呢?实际上是会的,但是同一个数字如果出现多次,必定是同时出现的。因为如果分开出现,那么较小的那个肯定不会再增加回来。

代码

#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]);
}