題目描述
小a和小b來到了一條佈滿了黃金的街道上。它們想要帶幾塊黃金回去,然而這裏的城管擔心他們拿走的太多,於是要求小a和小b通過做一個遊戲來決定最後得到的黃金的數量。
遊戲規則是這樣的:
假設道路長度爲n米(左端點爲0,右端點爲n),同時給出一個數k(下面會提到k的用法)
設小a初始時的黃金數量爲A,小b初始時的黃金數量爲B
小a從1出發走向n−1,小b從n−1出發走向1,兩人的速度均爲1m/s
假設某一時刻(必須爲整數)小a的位置爲x,小b的位置爲y,若gcd(n,x)=1且gcd(n,y)=1,那麼小a的黃金數量A會變爲A∗kx(kg),小b的黃金數量B會變爲B∗ky(kg)
當小a到達n−1時遊戲結束
小a想知道在遊戲結束時A+B的值
答案對109+7取模
輸入描述:
一行四個整數n,k,A,B
輸出描述:
輸出一個整數表示答案
示例1
輸入
4 2 1 1
輸出
32
說明
示例2
輸入
5 1 1 1
輸出
2
備註:
保證3⩽n⩽10^8,1⩽A,B,k⩽10^13
題解:
AC代碼:
套用歐拉函數模板和快速冪模板AC
#include<bits/stdc++.h>
using namespace std;
const long long m = 1e9 + 7;
#define LL long long
LL euler(LL n)
{
LL ans = n;
for (LL i = 2; i*i <= n; ++i) {
if (n%i == 0) {
ans -= ans / i;
while (n%i == 0) {
n /= i;
}
}
}
if (n > 1)ans -= ans / n;
return ans;
}
int fun(LL a, LL b, LL c)
{
LL res, t;
res = 1; //res記錄最後的模,初始化爲1
t = a % c;//t代表a^n,初始化爲a%c;
while (b)//當b不爲0時
{
if (b & 1)//如果b的二進制的最後一位是1,代表a^t存在
{
res = res * t%c;//更新最後的模
}
t = t * t%c;//t=a^n*a^n,向前走一位,例如a^8=a^4*a^4
b >>= 1;//b的二進制向右移動一位,去掉最後一位
}
return res;
}
int main()
{
LL n, k, a, b;
cin >> n >> k >> a >> b;
LL ans = 1;
LL x = euler(n)*n / 2;
LL t = k % m;
ans = fun(t, x, m);
cout << (a + b)*ans%m << endl;
}