0
点赞
收藏
分享

微信扫一扫

POJ - 2154 Color——Polya+欧拉函数优化


ans = 1/n*∑(0<=i && i < n)(n^gcd(i, n))

       = 1/n*∑(0<=i && i < n && n%i == 0)(euler(i) * n^i)

       = ∑(0<=i && i < n && n%i == 0)(euler(i) * n^(i-1))

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int euler(int x) {
int ans = x;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
ans = ans / i * (i - 1);
while (x % i == 0) x /= i;
}
}
if (x > 1) ans = ans / x * (x - 1);
return ans;
}
ll ipow(ll a, int n, int mod) {
ll ans = 1;
while (n) {
if (n & 1) ans = (ans * a) % mod;
a = (a * a) % mod;
n >>= 1;
}
return ans;
}
int main() {
int x, n, p;
scanf("%d", &x);
while (x--) {
scanf("%d%d", &n, &p);
ll ans = 0;
for (int i = 1; i * i <= n; i++) {
if (i * i == n) ans = (ans + ipow(n, i-1, p)*euler(i)) % p;
else if (n % i == 0) {
ans = (ans + ipow(n, i-1, p)*euler(n/i) + ipow(n, n/i-1, p) * euler(i)) % p;
}
}
printf("%lld\n", ans);
}
return 0;
}

 

举报

相关推荐

0 条评论