跳到主要内容

题解:P9441 [ICPC2021 WF] Fair Division

· 阅读需 3 分钟
Sintle
Developer

题目链接

解题思路

推导公式

设第 xx 个人拿到的钱为 F(x)F(x)

注意到 F(x)=mi=0(1f)in+xf\displaystyle F(x)=m\sum_{i=0}^{\infty}(1-f)^{in+x}f ,设 i=0(1f)in+x\displaystyle\sum_{i=0}^{\infty}(1-f)^{in+x}SS

S(1f)nS=(1f)xS-(1-f)^nS=(1-f)^x,可得 S=(1f)x1(1f)nS=\dfrac{(1-f)^x}{1-(1-f)^n}

所以 F(x)=(1f)x1(1f)nfmF(x)=\dfrac{(1-f)^x}{1-(1-f)^n}fm

t=(1f)=rqt=(1-f)=\dfrac{r}{q}

F(x)=tx1tn(1t)m=(rq)x(qrq)m1(rq)nF(x)=\dfrac{t^x}{1-t^n}(1-t)m=\dfrac{(\dfrac{r}{q})^x(\dfrac{q-r}{q})m}{1-(\dfrac{r}{q})^n}

上下同乘以 qnq^n 并化简得到 F(x)=rxqnx1(qr)mqnrnF(x)=\dfrac{r^xq^{n-x-1}(q-r)m}{q^n-r^n}

证明互质

对于 qq 的任何一个因数 aa,可得 aa 也是 qnq^n 的因数,而 rrqq 互质,故 aa 不是 rr 的因数,所以 aa 不是 qnrnq^n-r^n 的因数,但因为 aarxqnx1r^xq^{n-x-1} 的因数,所以 rxqnx1r^xq^{n-x-1}qnrnq^n-r^n 互质。证毕。

继续推导

因此,若要使 F(x)F(x) 为整数,qnrnq^n-r^n 必须能够整除 (qr)m(q-r)m

所以将 qnrnq^n-r^n 展开,得到 (qr)i=0nriqni1\displaystyle(q-r)\sum_{i=0}^{n}{r^{i}q^{n-i-1}}

注意到 (qr)(q-r) 已经出现了两次,所以不做考虑,只需要验证 i=0nriqni1\displaystyle\sum_{i=0}^{n}{r^{i}q^{n-i-1}} 能否整除 mm 即可。

因为 n6n\ge6,所以可以直接枚举 rrqq 的值。

同时 qn1q^{n-1} 需要不大于 mm,数据范围实际上并不大,只需要用 __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;
}