AHOI2002黑白瓷砖_Polya定理
2014-12-17 15:29
211 查看
终于把群论的一部分刷完了, 可喜可贺! 看了三次才看懂, 果然是非蒟蒻不能为也。
题目几乎是裸题, 其中一共有6种方案, 全部找出之后上polya定理即可。 先分步, 第一步, 翻转或者不翻转; 第二步, 不旋转,旋转120°或240°。
1、 不旋转且不翻转。 则原图中共有n*(n+1)/2个循环, 记为sum;
2、 不翻转, 旋转120°。 则原图与当前图会形成三元循环(图1), 若原图有中心砖块则还有一个单元循环(图2)。
图1
图2
故可知循环个数 = ceil(sum/3);
3、 不翻转, 旋转240°。 与120°相同。
4、 翻转, 不旋转。 我们可以发现原图被镜面对称了, 于是以中线为轴每对对称点形成一个新的循环, 这样就有了sum2 = 1+1+2+2+...+(n+1)/2个循环。(图3)
图3 图4
5、翻转并旋转120°。 其实这和以图中红色的线为轴的翻转是等价的(图4), 那么就和之前的情况一样共有sum2个循环。
6、翻转并旋转240°。 同上。
然后由polya定理可知等价类的个数ans = (2^sum+2*2^ceil(sum/3)+3*2^sum2) / 6, 到此结束。
题目几乎是裸题, 其中一共有6种方案, 全部找出之后上polya定理即可。 先分步, 第一步, 翻转或者不翻转; 第二步, 不旋转,旋转120°或240°。
1、 不旋转且不翻转。 则原图中共有n*(n+1)/2个循环, 记为sum;
2、 不翻转, 旋转120°。 则原图与当前图会形成三元循环(图1), 若原图有中心砖块则还有一个单元循环(图2)。
图1
图2
故可知循环个数 = ceil(sum/3);
3、 不翻转, 旋转240°。 与120°相同。
4、 翻转, 不旋转。 我们可以发现原图被镜面对称了, 于是以中线为轴每对对称点形成一个新的循环, 这样就有了sum2 = 1+1+2+2+...+(n+1)/2个循环。(图3)
图3 图4
5、翻转并旋转120°。 其实这和以图中红色的线为轴的翻转是等价的(图4), 那么就和之前的情况一样共有sum2个循环。
6、翻转并旋转240°。 同上。
然后由polya定理可知等价类的个数ans = (2^sum+2*2^ceil(sum/3)+3*2^sum2) / 6, 到此结束。
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define N 200 #define mod 10000 using namespace std; struct node { int len, l ; void clear() { len = 1; memset(l, 0, sizeof l); } void print() { printf("%d", l[len]); for (int i = len - 1; i; i--) printf("%04d", l[i]); putchar('\n'); } }ans; inline int max(int x, int y) { return x > y ? x : y; } void mul(node &a, node b) { node c; c.clear(); c.len = a.len + b.len - 1; for (int i = 1; i <= a.len; ++i) for (int j = 1; j <= b.len; ++j) c.l[i+j-1] += a.l[i] * b.l[j]; for (int i = 1; i <= c.len; ++i) { c.l[i+1] += c.l[i] / mod; c.l[i] %= mod; } while(c.l[c.len+1]) { ++c.len; c.l[c.len+1] += c.l[c.len] / mod; c.l[c.len] %= mod; } a = c; } void plus(node &a, node b) { a.len = max(a.len, b.len); for (int i = 1; i <= a.len; ++i) { a.l[i] += b.l[i]; a.l[i+1] += a.l[i] / mod; a.l[i] %= mod; } if (a.l[a.len+1]) ++a.len; } void div(node &a, int b) { int now = 0, flag = 0; for (int i = a.len; i; i--) { (now *= mod) += a.l[i]; a.l[i] = 0; if (now < b) continue; if (!flag) { flag = 1; a.len = i; } a.l[i] = now / b; now %= b; } } node pow(node a, int x) { node tmp; tmp.clear(); tmp.l[1] = 1; while(x) { if (x & 1) mul(tmp, a); mul(a, a); x >>= 1; } return tmp; } int main() { int n, sum, now = 0; scanf("%d", &n); sum = n * (n+1) / 2; node tmp; tmp.clear(); tmp.l[1] = 2; plus(ans, pow(tmp, sum)); plus(ans, pow(tmp, ceil((double)sum/3)+1)); for (int i = 1; i <= n; ++i) now += (i+1) / 2; plus(ans, pow(tmp, now)); plus(ans, pow(tmp, now)); plus(ans, pow(tmp, now)); div(ans, 6); ans.print(); return 0; }
相关文章推荐
- [wikioi2926][AHOI2002]黑白瓷砖(Polya定理)
- AHOI 2002 黑白瓷砖
- 【WIkiOI】【P2926】【黑白瓷砖】【Polya定理】【题解】
- #置换#Burnside引理Polya定理
- polya 定理总结
- HDU - 3923 - Invoker - (Polya定理,除法求逆元)
- POJ 2409 Let it Bead【polya 计数法,burnside定理】
- 多校第9场HDU3923Invoker(polya定理)
- poj 2409 Let it Bead(polya 定理)
- ACM中的【数学知识】之【组合数学】(一) Polya定理的简单理解 POJ 1286
- poj 1286 和 2409 (polya 定理)
- HDU 4633 Who's Aunt Zhang ★(Polya定理 + 除法取模)
- POJ 2409 Let it Bead(Polya定理)
- POJ 2154-Color(Polya定理-旋转 串项链)
- ACM-polya定理
- Pólya 定理(草稿)
- Polya定理,Burnside引理
- POJ 2409 - Let it Bead【Polya定理】
- POJ2409 Let it Bead【Polya定理】
- 波利亚polya定理的学习(解决涂色问题)