BZOJ1815 [Shoi2006]color 有色图

<div class="post_brief"><p> 一道burnside,做了几次之后感觉比较经典了。然后发现网上居然没有题解。</p>   枚举正整数拆分,既每个质换的长度。然后枚举gcd算每类置换的贡献。再用错排公式来算每类置换的数量。然后求和。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define _l (long long int) const int maxn = 63; int n, m, mod, ans, g[maxn][maxn]; int sq[maxn], tq, fac[maxn], finv[maxn], vinv[maxn]; int modPow(int a, int x) { int s(1); for (; x; x >>= 1, a = _l a * a % mod) if (x & 1) s = _l s * a % mod; return s; }...

February 4, 2015 · 2 min · laekov

POJ2154 Color

<div class="post_brief"><p> 首先是burnside,对于旋转x下都要当作一个置换,所以总共有n个。然后第i个的不动点数量等于n<sup>gcd(n,i)</sup>,然后统计一下个数是phi(gcd(n,i))个。</p>   然后发现要用奇奇怪怪的东西来求phi。我用的方法是分解质因数然后DFS,跑得飞快。   #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define _l (long long int) const int maxn = 50009; int n, mod; int tp, pn[maxn], phi[maxn]; bool pr[maxn]; void pre() { memset(pr, 0, sizeof(pr)); tp = 0; phi[1] = 1; for (int i = 2; i < maxn; ++ i) { if (!pr[i]) { pn[tp ++] = i; phi[i] = i - 1; } for (int j = 0; j < tp && i * pn[j] < maxn; ++ j) { pr[i * pn[j]] = 1; if (i % pn[j] == 0) { phi[i * pn[j]] = phi[i] * pn[j]; break; } else phi[i * pn[j]] = phi[i] * phi[pn[j]]; } } }...

January 31, 2015 · 2 min · laekov