题目描述
小a和小b来到了一条布满了黄金的街道上。它们想要带几块黄金回去,然而这里的城管担心他们拿走的太多,于是要求小a和小b通过做一个游戏来决定最后得到的黄金的数量。
游戏规则是这样的:
假设道路长度为n米(左端点为0,右端点为n),同时给出一个数k(下面会提到kk的用法)
设小a初始时的黄金数量为A,小b初始时的黄金数量为B
小a从1出发走向n−1,小b从n−1出发走向11,两人的速度均为1m/s
假设某一时刻(必须为整数)小a的位置为x,小b的位置为y,若gcd(n,x)=1且gcd(n,y)=1,那么小a的黄金数量A会变为A∗ (kg),小b的黄金数量B会变为B∗
(kg)
当小a到达n−1时游戏结束
小a想知道在游戏结束时A+BA+B的值
答案对109+7取模
输入描述:
一行四个整数n,k,A,B;
输出描述:
输出一个整数表示答案
输入
4 2 1 1
5 1 1 1
输出
32
2
备注:
保证3⩽n⩽,1⩽A,B,k⩽
多打几个表会发现,只要gcd(a,n)==1,那么gcd(n-a,n)也一定等于1
A=A∗
B=B∗
当A从1走到n-1时,A就走完了所有的与n互质的数,所以A=A* (sumn是小于n的并且与n互质的数的和)
小于n的并且与n互质的数的和就ok了
根据欧拉公式可以得出这个和:sumn=
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
ll k,A,B,n,sum;
const ll mod=1e9+7;
ll gcd(ll a,ll b){
if(b==0)return a;
return gcd(b,a%b);
}
ll ksm(ll a,ll b){
ll an=1;
while(b) {
if(b&1)an=an*a%mod;
a=a*a%mod;
b>>=1;
}
return an;
}
ll init(ll n){
ll ans=n;
for(ll i=2;i*i<=n;i++)
if(n%i==0){
ans=ans/i*(i-1);
while(n%i==0)n/=i;
}
if(n>1) ans=ans/n*(n-1);
return ans;
}
int main(){
scanf("%lld%lld%lld%lld",&n,&k,&A,&B);
ll ss=init(n);
ll sum=n*ss>>((ll)1);
printf("%lld\n",((A+B)%mod)*ksm(sum,k)%mod);
return 0;
}