题目描述
小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;
}