牛客寒假算法基础集训营1 D 小a与黄金街道

链接:https://ac.nowcoder.com/acm/contest/317/D
来源:牛客网

题解思路:

首先若gcd(n, x) = 1,那么gcd(n, n − x)一定等于1

同时不难发现,若小a在某个位置获得了kx的贡献,

那么一定存在一个位置会获得kn-x的贡献,而且两个人的贡献是相同的!

把小a的贡献单独写出来即为 

考虑如何快速得到R的值,观察题目描述不难发现,能产生答案的数一定是与n互质的数,这与ϕ函数的定义是相同的!

又因为前n个数的欧拉函数之和为ϕ(n)*n/2

也可以直接容斥算约数的贡献
因此最终的答案为(A + B) ∗ Kϕ(n)*n/2

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 
 5 //欧拉函数:与n互质的整数个数(从1到n)
 6 ll euler(ll n)
 7 {
 8     ll res=n,a=n;
 9     for(ll i=2;i*i<=a;i++)
10     {
11         if(a%i==0)
12         {
13             res=res/i*(i-1);//先进行除法是为了防止溢出
14             while(a%i==0)a/=i;
15         }
16     }
17     if(a>1)res=res/a*(a-1);
18     return res;
19 }
20 
21 ll PowerMod(ll a, ll b, ll c)
22 {
23     ll ans = 1;
24     a = a % c;
25     while(b>0) {
26         if(b % 2 == 1)
27         ans = (ans * a) % c;
28         b = b/2;
29         a = (a * a) % c;
30     }
31     return ans;
32 }
33 int main()
34 {
35     ll n,k,a,b;
36     while(cin >> n >> k >> a >> b)
37     {
38         ll ans;
39         ll mod = 1e9 + 7;
40         ll re = euler(n) / 2 * n;
41         ans = (a + b) * PowerMod(k,re,mod) % mod;
42         cout << ans << endl;
43     }
44     return 0;
45 }

猜你喜欢

转载自www.cnblogs.com/lu1nacy/p/10351072.html