2016 Multi-University Training Contest 1 1006 PowMod

来源:互联网 发布:c语言区间内素数 编辑:程序博客网 时间:2024/05/02 00:28

题目链接:点击打开链接

题目大意:!!!!!!!很吓人的数学取模

解题思路:这次真的不好意思挂原创啊,因为完全是按照官方题解来打的,数学差没办法。

以上是官方题解给出的公式:官方题解

代码:

#include<iostream>#include<vector>#include<cmath>#include<algorithm>#include<ctime>#include "cstdio"#include "string"#include "string.h"#include "map"using namespace std;const int maxn = 10000001;const int mod = 1000000007;int vis[maxn], phi[maxn], prime[maxn], pt, a[20];long long sum[maxn];void init(){pt = 0;phi[1] = 1;int N = maxn;int k;for (int i = 2;i<N;i++){if (!vis[i])prime[pt++] = vis[i] = i, phi[i] = i - 1;for (int j = 0;j<pt && (k = prime[j] * i)<N;j++){vis[k] = prime[j];if (vis[i] == prime[j]){phi[k] = phi[i] * prime[j];break;}elsephi[k] = phi[i] * (prime[j] - 1);}}}long long pow(long long a, long long n, long long mod){long long base = a, ret = 1;while (n){if (n % 2)ret = (ret*base) % mod;base = (base*base) % mod;n /= 2;}return ret;}long long cal_sum(int pos, long long n, long long m){if (n == 1)//sum(1,m)=sigma(phi(i))return sum[m];if (m == 0)//sum(n,0)=0;return 0;return ((a[pos] - 1)*cal_sum(pos - 1, n / a[pos], m) % mod + cal_sum(pos, n, m / a[pos])) % mod;//sum(n,m)=phi(p)*sum(n/p,m)+sum(n,m/p),p为质数}long long cal_ans(long long k, long long mod){if (mod == 1)return 0;long long temp = cal_ans(k, phi[mod]);//b%phi(p)long long ans = (pow(k,temp+phi[mod],mod)+mod)%mod;return ans;}int main(){init();sum[0] = 0;for (int i = 1;i < maxn;i++)sum[i] = (sum[i - 1] + phi[i]) % mod;int n, m, p;while (scanf("%d %d %d", &n, &m, &p) != EOF){int now = n, num = 0;for (int i = 0;i < pt;i++){if (!vis[n])//n是质数{a[num++] = now;break;}if (now%prime[i] == 0)//分解质因数{a[num++] = prime[i];now /= prime[i];}}long long temp = cal_sum(num - 1, n, m);long long ans = cal_ans(temp, p);printf("%lld\n", ans);}return 0;}


0 0
原创粉丝点击