https://www.luogu.org/problem/P4980
题意:很简单的,就一个最简单的polya定理。
做法:网上随便看看吧,写得都不错。
我们要求的就是上面的式子,我们容易知道|G|=n,|B|=n;
但不过重点就是c(g);
但不动的时候 c(g)=n这点没有毛病吧,因为都没有动。
但动k个点时候,这个时候就要看k了,随便找一找规律就知道这个就是 gcd(n,i)。
如果这个不知道,就仔细看看polya定理,并且看看手推一下简单样例。
然后随便处理一下就可以了。注意答案会爆long long
#include "bits/stdc++.h"
using namespace std;
const int maxn = 300000 + 10;
//typedef long long ll;
typedef __int128 ll;
const ll mod = 1000000000 + 7;
ll quick(ll a, ll n, ll p) {
ll ans = 1;
for (; n; n >>= 1, a = a * a % p)
if (n & 1) ans = ans * a % p;
return ans;
}
void print(__int128 x) {
if (!x) {
puts("0");
return;
}
string ret = "";
while (x) {
ret += x % 10 + '0';
x /= 10;
}
reverse(ret.begin(), ret.end());
cout << ret << endl;
}
int pri[maxn], phi[maxn], vis[maxn], cnt;
void init() {
vis[1] = phi[1] = 1;
for (int i = 2; i < maxn; i++) {
if (!vis[i]) {
pri[++cnt] = i;
phi[i] = i - 1;
}
for (int j = 1; j <= cnt && i * pri[j] < maxn; j++) {
vis[i * pri[j]] = 1;
if (i % pri[j] == 0) {
phi[i * pri[j]] = phi[i] * pri[j];
break;
}
phi[i * pri[j]] = phi[i] * (pri[j] - 1);
}
}
}
//unordered_map<ll, ll> mp;
ll euler(ll n) {
if (n < maxn) return phi[n];
// if (mp.count(x)) return mp[n];
ll ret = 1;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
n /= i, ret *= (i - 1);
while (n % i == 0) n /= i, ret *= i;
}
}
if (n > 1) ret *= (n - 1);
return ret;
}
ll solve(long long n) {
ll ans = 0;
for (ll i = 1; i * i <= n; i++) {
if (n % i != 0) continue;
ans += quick(n, i - 1, mod) * euler(n / i) % mod;
ans %= mod;
if (i * i == n) continue;
if (n % i == 0) {
ans += quick(n, n / i - 1, mod) * euler(i) % mod;
ans %= mod;
}
}
return ans;
}
int main() {
// ios::sync_with_stdio(false);
// cin.tie(0);
// cout.tie(0);
init();
int T;
long long n;
cin >> T;
while (T--) {
cin >> n;
print(solve(n));
}
return 0;
}