I first heard about Polya principle is NOIP2017 before, but I think it is too difficult to learn thinking about the future;
NOIP2018 I used to think this stuff Examination, determined to learn, and later the cushions;
WC2019 I used to think this stuff Examination, determined to learn, and later the cushions;
SNOI2019 I used to think this stuff Examination, determined to learn, and later the cushions;
CTS2019 I used to think this stuff Examination, determined to learn, and later the cushions;
APIO2019 I used to think this stuff Examination, determined to learn, and later the cushions;
THUSC2019 I used to think this stuff Examination, determined to learn, and later the cushions;
NOI2019 less than a week from today, I was determined to learn, and quickly grabbed jumpmelon let him tell me, then he said two words is over.
Fall .jpg
Since Polya principle is that I temporarily hold melon foot school, so this blog is not only rigorous conclusions, a rigorous proof of what the NOI and subsequent statements depend on mood Supplemented.
For these reasons, this blog Tucao link may be longer than the text (without the code)
Problems: There is a \ (n-\) points and rings \ (m \) colors, each seeking to different dyed color scheme nature number. Essentially different two programs if and only if they can not be obtained by rotating each other.
Conclusion: Program number is \ (\ frac {1} { n} \ sum_ {i = 1} ^ nm ^ {\ gcd (n, i)} \)
Example: Luo Gu 4980 Polya Theorem
Direct push routine Jiuhaola formula:
\[ \begin{aligned} ans&=\frac{1}{n}\sum_{i=1}^n n^{\gcd(n,i)}\\ &=\frac{1}{n}\sum_{d|n}n^d\sum_{i=1}^{\frac{n}{d}}[gcd(\frac{n}{d},i)=1]\\ &=\frac{1}{n}\sum_{d|n}n^d\varphi(\frac{n}{d}) \end{aligned}\]
To \ (n \) to maintain it when the decomposition of the quality factor then search all of its factor, quality factor search by \ (\ varphi \) just fine
Code:
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
namespace zyt
{
template<typename T>
inline bool read(T &x)
{
char c;
bool f = false;
x = 0;
do
c = getchar();
while (c != EOF && c != '-' && !isdigit(c));
if (c == EOF)
return false;
if (c == '-')
f = true, c = getchar();
do
x = x * 10 + c - '0', c = getchar();
while (isdigit(c));
if (f)
x = -x;
return true;
}
template<typename T>
inline void write(T x)
{
static char buf[20];
char *pos = buf;
if (x < 0)
putchar('-'), x = -x;
do
*pos++ = x % 10 + '0';
while (x /= 10);
while (pos > buf)
putchar(*--pos);
}
typedef long long ll;
typedef pair<int, int> pii;
const int SQRTN = 4e4 + 10, P = 1e9 + 7;
pii prime[SQRTN];
int pcnt, n, ans;
int power(int a, int b)
{
int ans = 1;
while (b)
{
if (b & 1)
ans = (ll)ans * a % P;
a = (ll)a * a % P;
b >>= 1;
}
return ans;
}
int inv(const int a)
{
return power(a, P - 2);
}
void get_prime(int n)
{
pcnt = 0;
for (int i = 2; i * i <= n; i++)
if (n % i == 0)
{
prime[pcnt++] = pii(i, 0);
while (n % i == 0)
++prime[pcnt - 1].second, n /= i;
}
if (n > 1)
prime[pcnt++] = pii(n, 1);
}
void dfs(const int pos, const int mul, const int pmul, const int div)
{
if (pos == pcnt)
{
ans = (ans + (ll)mul / div * pmul * power(n, n / mul)) % P;
return;
}
dfs(pos + 1, mul, pmul, div);
for (int i = 1, tmp = prime[pos].first; i <= prime[pos].second; i++, tmp *= prime[pos].first)
dfs(pos + 1, mul * tmp, pmul * (prime[pos].first - 1), div * (prime[pos].first));
}
int work()
{
int T;
read(T);
while (T--)
{
ans = 0;
read(n);
get_prime(n);
dfs(0, 1, 1, 1);
write((ll)ans * inv(n) % P), putchar('\n');;
}
return 0;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("4980.in", "r", stdin);
#endif
return zyt::work();
}