Magic Bracelet
Time Limit: 2000MS   Memory Limit: 131072K
Total Submissions: 3731   Accepted: 1227

Description

Ginny’s birthday is coming soon. Harry Potter is preparing a birthday present for his new girlfriend. The present is a magic bracelet which consists of n magic beads. The are m kinds of different magic beads. Each kind of beads has its unique characteristic. Stringing many beads together a beautiful circular magic bracelet will be made. As Harry Potter’s friend Hermione has pointed out, beads of certain pairs of kinds will interact with each other and explode, Harry Potter must be very careful to make sure that beads of these pairs are not stringed next to each other.

There infinite beads of each kind. How many different bracelets can Harry make if repetitions produced by rotation around the center of the bracelet are neglected? Find the answer taken modulo 9973.

Input

The first line of the input contains the number of test cases.

Each test cases starts with a line containing three integers n (1 ≤ n ≤ 109gcd(n, 9973) = 1), m (1 ≤ m ≤ 10), k (1 ≤ k ≤ m(m − 1) ⁄ 2). The next k lines each contain two integers a and b(1 ≤ ab ≤ m), indicating beads of kind a cannot be stringed to beads of kind b.

Output

Output the answer of each test case on a separate line.

Sample Input

4
3 2 0
3 2 1
1 2
3 2 2
1 1
1 2
3 2 3
1 1
1 2
2 2

Sample Output

4
2
1
0

Source

 
 
很好的一道题目。
做了这题才感觉对Burnside引理和polya定理有点深入了解。
 
 
还不清楚的可以看看上面的链接,解释的很清楚。
 
关于这题,给个解释的很清楚的http://hi.baidu.com/billdu/item/62319f2554c7cac9a5275a0d
 
讲得很清晰
 
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
using namespace std;
const int MOD = ;
//矩阵
struct Matrix
{
int mat[][];
int n,m;
Matrix(){}
Matrix(int _n,int _m)
{
n = _n; m = _m;
for(int i = ;i < n;i++)
for(int j = ;j < m;j++)
mat[i][j] = ;
}
Matrix operator *(const Matrix &b)const
{
Matrix ret = Matrix(n,b.m);
for(int i = ;i < ret.n;i++)
for(int j = ;j < ret.m;j++)
{
for(int k = ;k < m;k++)
{
ret.mat[i][j] += mat[i][k]*b.mat[k][j];
ret.mat[i][j] %= MOD;
}
}
return ret;
}
Matrix operator ^(int b)const
{
Matrix ret = Matrix(n,m),tmp = Matrix(n,m);
for(int i = ;i < n;i++)
{
for(int j = ;j < m;j++)
tmp.mat[i][j] = mat[i][j];
ret.mat[i][i] = ;
}
while(b)
{
if(b&)ret = ret*tmp;
tmp = tmp*tmp;
b >>= ;
}
return ret;
}
};
//求欧拉函数
long long eular(long long n)
{
long long ans = n;
for(int i = ;i*i <= n;i++)
{
if(n % i == )
{
ans -= ans/i;
while(n % i == )
n /= i;
}
}
if(n > )ans -= ans/n;
return ans;
}
//快速幂,用来求逆元
long long pow_m(long long a,long long n,long long mod)
{
long long ret = ;
long long tmp = a%mod;
while(n)
{
if(n&)
{
ret *= tmp;
ret %= mod;
}
tmp *= tmp;
tmp %= mod;
n>>=;
}
return ret;
}
//利用欧拉定理求逆元
long long inv(long long x,long long mod)//mod为素数
{
return pow_m(x,mod-,mod);
} Matrix A,B;
int n,m;
//求x个元素对应的f
int NoChange(int x)
{
B = A^x;
int ans = ;
for(int i = ; i < m;i++)
{
ans += B.mat[i][i];
ans %= MOD;
}
return ans;
}
int solve()
{
int ans = ;
for(int i = ;i*i <= n;i++)
if(n % i == )
{
ans = ans + eular(i)*NoChange(n/i)%MOD;
ans %= MOD;
if(n/i != i)
{
ans = ans + eular(n/i)*NoChange(i)%MOD;
ans %= MOD;
}
}
ans *= inv(n,MOD);
return ans%MOD;
}
int main()
{
int T;
int k;
int u,v;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
A = Matrix(m,m);
for(int i = ;i < m;i++)
for(int j = ;j < m;j++)
A.mat[i][j] = ;
while(k--)
{
scanf("%d%d",&u,&v);
u--;
v--;
A.mat[u][v] = A.mat[v][u] = ;
}
printf("%d\n",solve());
}
return ;
}

POJ 2888 Magic Bracelet(Burnside引理,矩阵优化)的更多相关文章

  1. POJ 2888 Magic Bracelet ——Burnside引理

    [题目分析] 同样是Burnside引理.但是有几种颜色是不能放在一起的. 所以DP就好了. 然后T掉 所以矩阵乘法就好了. 然后T掉 所以取模取的少一些,矩阵乘法里的取模尤其要注意,就可以了. A掉 ...

  2. POJ-2888 Magic Bracelet(Burnside引理+矩阵优化+欧拉函数+逆元)

    Burnside引理经典好题呀! 题解参考 https://blog.csdn.net/maxwei_wzj/article/details/73024349#commentBox 这位大佬的. 这题 ...

  3. poj 2888 Magic Bracelet(Polya+矩阵快速幂)

    Magic Bracelet Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 4990   Accepted: 1610 D ...

  4. 【POJ2888】Magic Bracelet Burnside引理+欧拉函数+矩阵乘法

    [POJ2888]Magic Bracelet 题意:一个长度为n的项链,有m种颜色的珠子,有k个限制(a,b)表示颜色为a的珠子和颜色为b的珠子不能相邻,求用m种珠子能串成的项链有多少种.如果一个项 ...

  5. poj 2888 Magic Bracelet

    经典的有限制条件的Burnside计数+矩阵乘法!!! 对于这种限制条件的情况我们可以通过矩阵连乘得到,先初始化矩阵array[i][j]为1.如果颜色a和颜色b不能涂在相邻的珠子, 那么array[ ...

  6. 解题:POJ 2888 Magic Bracelet

    题面 这题虽然很老了但是挺好的 仍然套Burnside引理(因为有限制你并不能套Polya定理),思路和这个题一样,问题主要是如何求方案. 思路是把放珠子的方案看成一张图,然后就巧妙的变成了一个经典的 ...

  7. POJ 2888 Magic Bracelet(burnside引理+矩阵)

    题意:一个长度为n的项链,m种颜色染色每个珠子.一些限制给出有些颜色珠子不能相邻.旋转后相同视为相同.有多少种不同的项链? 思路:这题有点综合,首先,我们对于每个n的因数i,都考虑这个因数i下的不变置 ...

  8. [POJ 2888]Magic Bracelet[Polya Burnside 置换 矩阵]

    也许更好的阅读体验 \(\mathcal{Description}\) 大意:给一条长度为\(n\)的项链,有\(m\)种颜色,另有\(k\)条限制,每条限制为不允许\(x,y\)颜色连在一起.要求有 ...

  9. POJ 2888 Magic Bracelet [Polya 矩阵乘法]

    传送门 题意:竟然扯到哈利波特了.... 和上一题差不多,但颜色数很少,给出不能相邻的颜色对 可以相邻的连边建图矩阵乘法求回路个数就得到$f(i)$了.... 感觉这样的环上有限制问题挺套路的...旋 ...

随机推荐

  1. @jsonignore的作用

    作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响. 如下: package com.hzboy.orm; import java.util.List; impor ...

  2. BZOJ3028: 食物

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3028 题解:列出母函数乘起来化简之后再展开,用插板法即可. 代码: #include<c ...

  3. 微信公共服务平台开发(.Net 的实现)5-------解决access_token过期的问题(转)

    因为access_token,在以后的高级功能里面会经常用到,所以这里不得不这里对前面所讲解的access_token改造一下.另外需要说明的是access_token是变化的,有自己的周期,官方解释 ...

  4. 修改Android系统字号(二)

    /*********************************************************************** * 修改Android系统字号(二) * 说明: * ...

  5. Android MVPR 架构模式

    最近我在尝试让 Google 的 IO App 变得可单元测试,我这样做的其中一个原因是验证 Freeman 和 Pryce 在引用中对单元测试的总结.即使现在我还是没有把 IOSched 中的任何一 ...

  6. MongoDB数据库和集合的状态信息

    查看数据库统计信息:db.stats()  > use testswitched to db test> db.stats(){        "db" : " ...

  7. 【LeetCode】58 - Length of Last Word

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...

  8. 批量还原数据库 SQL Server 2008

    1.如果你够懒,不想一步一步点路径,一步一步选择 2.如果你连单个备份数据库的存储过程都不想多执行,一般每还原一个需要修改数据库名 下面的脚本适合你: /*********************** ...

  9. MATLAB Coder从MATLAB生成C/C++代码步骤

    MATLAB Coder可以从MATLAB代码生成独立的.可读性强.可移植的C/C++代码. 使用MATLAB Coder产生代码的3个步骤: 准备用于产生代码的MATLAB算法: 检查MATLAB代 ...

  10. 【24点游戏】cocos2dx 源码

    1.  4个数字 24点判断 double Calc(double a, double b, string oper) { double result = 0; const char *p = ope ...