题意:一个长度为n的项链,m种颜色染色每个珠子。一些限制给出有些颜色珠子不能相邻。旋转后相同视为相同。有多少种不同的项链?

思路:这题有点综合,首先,我们对于每个n的因数i,都考虑这个因数i下的不变置换个数,然后乘以(n/i)的欧拉函数加到ans上面,然后再让ans乘以n在模p下的逆元。至于怎么求因数i下的不变置换个数,相信大家都做过没有限制的,至于有限制的,大家可以考虑一下这样:初始数组a[m][m]都为1,对于每个限制x,y,都令a[x][y]=a[y][x]=0,我们有一个数列:b1,b2,b3,b4...bm,那么对于每个i∈[1,m-1],都有a[bi][bi+1]=1,这样想到了什么?就是矩阵乘法,对于刚刚的矩阵a我们让s=a^i,然后把每个a[i][i]加起来,这样就代表:每个i出发又回到i的方法数,这样就变成因数i下的不变置换个数了!

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
const int Mod=;
int a[][],b[][],c[][],s[][],n,m,K;
int read(){
char ch=getchar();
int t=,f=;
while (ch<''||ch>''){
if (ch=='-') f=-;
ch=getchar();
}
while (''<=ch&&ch<=''){
t=t*+ch-'';
ch=getchar();
}
return t*f;
}
void exgcd(int a,int b,int &x,int &y){
if (b==){
x=;
y=;
return;
}
exgcd(b,a%b,x,y);
int t=x;
x=y;
y=(t-a/b*y);
}
int inv(int n){
int A,B,x,y;
A=n;B=Mod;
exgcd(A,B,x,y);
return (x+Mod)%Mod;
}
int euler(int n){
int res=n,a=n;
for (int i=;i*i<=n;i++)
if (a%i==){
res=res/i*(i-);
while (a%i==) a/=i;
}
if (a>) res=res/a*(a-);
return res%Mod;
}
void mult_matrix1(){
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
c[i][j]=;
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
for (int k=;k<=m;k++)
c[i][j]=(c[i][j]+s[i][k]*b[k][j])%Mod;
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
s[i][j]=c[i][j];
}
void mult_matrix2(){
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
c[i][j]=;
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
for (int k=;k<=m;k++)
c[i][j]=(c[i][j]+b[i][k]*b[k][j])%Mod;
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
b[i][j]=c[i][j];
}
int work(int x){
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
b[i][j]=a[i][j],s[i][j]=;
int ans=;
for (int i=;i<=m;i++)
s[i][i]=;
while (x){
if (x%) mult_matrix1();
mult_matrix2();
x/=;
}
for (int i=;i<=m;i++) ans=(ans+s[i][i])%Mod;
return ans;
}
int main(){
int T=read();
while (T--){
n=read();m=read();K=read();
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
a[i][j]=;
for (int i=;i<=K;i++){
int x=read(),y=read();
a[x][y]=a[y][x]=;
}
int ans=;
for (int i=;i*i<=n;i++)
if (n%i==){
ans=(ans+work(i)*euler(n/i))%Mod;
if (i*i!=n)
ans=(ans+work(n/i)*euler(i))%Mod;
}
ans=(ans*inv(n%Mod))%Mod;
printf("%d\n",ans);
}
}

POJ 2888 Magic Bracelet(burnside引理+矩阵)的更多相关文章

  1. POJ 2888 Magic Bracelet ——Burnside引理

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

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

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

  3. POJ 2888 Magic Bracelet(Burnside引理,矩阵优化)

    Magic Bracelet Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 3731   Accepted: 1227 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[Polya Burnside 置换 矩阵]

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

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

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

  9. poj 2888 Magic Bracelet <polya定理>

    题目:http://poj.org/problem?id=2888 题意:给定n(n <= 10^9)颗珠子,组成一串项链,每颗珠子可以用m种颜色中一种来涂色,如果两种涂色方法通过旋转项链可以得 ...

随机推荐

  1. CCI_chapter 8 Recurision

    8.1 水题 8.2 Imagine a robot sitting on the upper left hand corner of an NxN grid The robot can only m ...

  2. logstash tag使用说明

    zjtest7-frontend:/usr/local/logstash-2.3.4/config# cat stdin04.conf input { stdin { } } filter { # d ...

  3. mysql join 的同时可以筛选数据

    看sql ) ) group by a.id; 这里面用了多个子查询,与join关联. 其中 不仅有关联条件,还对sh_mall_goods表进行了筛选,只选出mall_id为9的数据,进行关联. 这 ...

  4. Linux企业级项目实践之网络爬虫(9)——通过URL抓取网页内容

    基本URL包含模式(或称协议).服务器名称(或IP地址).路径和文件名,如"协议://授权/路径?查询".完整的.带有授权部分的普通统一资源标志符语法看上去如下:协议://用户名: ...

  5. FutureTask 测试用例

    package currentTest.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent ...

  6. Linux远程访问windows时,出现"连接被对端重置"错误

    1.sudo apt-get install rdesktop 需要下载 152 kB 的软件包.       解压缩后会消耗掉 512 kB 的额外空间. 2.运行时出现错误 root@oskey- ...

  7. SQL 使用经验

    1. 写存储过程,Update数据库表,一定要根据idRow,也就是主键唯一键来更新. 更新操作,如果根据其他条件更新,之后就有的忙活了. 2. Query语句要加NOLOCK

  8. poj 3009 Curling 2.0 (dfs )

    Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11879   Accepted: 5028 Desc ...

  9. Android实现左右滑动效果

    本示例演示在Android中实现图片左右滑动效果.   关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来 ...

  10. 搭建LAMP架构

    1. 为什么下载源码包需要到官网上去下载?简单说就是为了安全,如果是非官方下载的源码包,有可能被别有用心的人动过手脚. 2. 64位机器是否可以安装32位rpm包?64位机器是否可以安装32位的mys ...