题目描述

小凯手中有两种面值的金币,两种面值均为正整数且彼此互素。每种金币小凯都有无数个。在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的。现在小凯想知道在无法准确支付的物品中,最贵的价值是多少金币?注意:输入数据保证存在小凯无法准确支付的商品。

输入描述:

输入数据仅一行,包含两个正整数 a 和 b,它们之间用一个空格隔开,表示小凯手中金币的面值。

输出描述:

输出文件仅一行,一个正整数 N,表示不找零的情况下,小凯用手中的金币不能准确支付的最贵的物品的价值。

示例1

输入
3 7
输出
11
说明
小凯手中有面值为3和7的金币无数个,在不找零的前提下无法准确支付价值为 1、2、4、5、8、11的物品,其中最贵的物品价值为11。
比11贵的物品都能买到,比如:
12 = 3 x 4 + 7 x 0
13 = 3 x 2 + 7 x1
14 = 3 x 0 + 7 x 2
15 = 3 x 5 + 7 x 0

备注

对于 30% 的数据:1 ≤ a,b ≤ 50;
对于 60% 的数据: 1 ≤ a,b ≤ 10,000;
对于 100% 的数据:1 ≤ a,b ≤ 1,000,000,000。

解答

一种图论的理解方法: 同余类最短路.

 , 然后将所有的数按照对 取模的余数分成  个剩余类. 每个同余类看成一个点, 即 . 设  为第 类数中最小的可以被表示出来的数, 则  . 由于  , 对 来说,  一定大于  (当  时  , 显然不能被表示出来). 而每一个 都是由一个别的什么数加上  得到的(在模  意义下且  互质). 所以就可以从点 向点 连一条长度为b的有向边(意味着加上  得到下一个数), 然后就能转移了! 显然  , 那么从  开始跑一个单源最短路, 球出每个剩余类中最小的可以被表示出来的数.

可是, 球了这个有什么猫用吗??

如果  是每个剩余类中最小的可以被表示出来的数, 那  不就是最大的不能被表示出来的数吗! 可以理解成每个剩余类中的数都是  这样排列的(  时). 假设求出来的  , 那么之后的所有数都可以由它加上若干个  得出. 因此 就是最大的不能被表示的数了. 在所有的 里取最大就是答案.

但是这题只让写两行代码, 怎么跑最短路??还不如打个循环暴力

于是手动模拟一波跑最短路的过程: 每个点都只有一条出边, 形成了一个环. 这个很明显吧, 因为  互质. 所以最大的  就是 . 边权都是 , 所以  , 再减去一个 就得到了那个简短而凝聚着人类智慧结晶的公式: 

代码:

#include<iostream>
#include<cstdio>
using namespace std;

int main()
{
    long long a,b;
    cin>>a>>b;
    cout<<a*b-a-b;
}


来源:matsuk