题解:P9441 [ICPC2021 WF] Fair Division
· 阅读需 3 分钟
题目链接
解题思路
推导公式
设第 个人拿到的钱为 。
注意到 ,设 为 。
则 ,可得 。
所以 。
设 。
则 。
上下同乘以 并化简得到 。
证明互质
对于 的任何一个因数 ,可得 也是 的因数,而 与 互质,故 不是 的因数,所以 不是 的因数,但因为 是 的因数,所以 与 互质。证毕。
继续推导
因此,若要使 为整数, 必须能够整除 。
所以将 展开,得到 。
注意到 已经出现了两次,所以不做考虑,只需要验证 能否整除 即可。
因为 ,所以可以直接枚举 和 的值。
同时 需要不大于 ,数据范围实际上并不大,只需要用 __int128
确保在运算过程中不会超出范围即可。
参考代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
static const int INF = 2e18;
int n , m;
int mul(int a , int b)
{
return min(((__int128_t)a) * b , (__int128_t)INF);
}
int fpow(__int128 a , int b)
{
int res = 1;
while(b)
{
if(b & 1)
{
res = mul(res , a);
}
a = mul(a , a);
b >>= 1;
}
return res;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for(int q = 2 ; fpow(q , n - 1) <= m && fpow(q , n - 1) != 2147483647 ; q++)
{
for(int r = 1 ; r < q ; r++)
{
int num = 0;
for(int i = 0 ; i < n ; i++)
{
num = min(num + mul(fpow(r , i) , fpow(q , n - i - 1)) , INF);
}
if(m % num == 0)
{
cout << q - r << " " << q << '\n';
return 0;
}
}
}
cout << "impossible" << '\n';
return 0;
}