题意:一个长度为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. 自制单片机之七……扩展:DS18B20温度测量

    DS18B20数字温度测量传感器,网上介绍很多,我就不罗嗦了.见图 DS18B20与前产品DS1820的不同: DS18B20继承了DS1820的全部优点,并做了如下改进 1.供电范围扩大为3.0-- ...

  2. 【Xamarin For IOS 开发需要的安装文件】

    官网安装文件下载: http://download.xamarin.com/XamarinforMac/Mac/xamarin.mac-2.0.1.64.pkghttp://download.xama ...

  3. Android 最简单的SD卡文件遍历程序

    package com.wenhao.test.sddemo; import java.io.File; import android.app.Activity; import android.os. ...

  4. (7)如何得到所有的 "水仙花数" ?

    本程序转载自:如何得到所有的水仙花数 感谢Android_iPhone(日知己所无),preferme(冰思雨)等人: package test; import java.math.BigIntege ...

  5. Android Studio:You need to use a Theme.AppCompat theme (or descendant) with this activity. AlertDialog

    学习<第一行代码>的时候遇到的问题. Process: com.example.sevenun.littledemo, PID: 2085 java.lang.RuntimeExcepti ...

  6. poj 2392 Space Elevator(多重背包+先排序)

    Description The cows are going to space! They plan to achieve orbit by building a sort of space elev ...

  7. poj 2041 Unreliable Message 字符串处理

    水的问题.直接附着到代码. //poj 2041 //sep9 #include <iostream> using namespace std; char mode[128]; char ...

  8. Enabling Active Directory Authentication for VMWare Server running on Linux《转载》

    Enabling Active Directory Authentication for VMWare Server running on Linux Version 0.2 - Adam Breid ...

  9. Stm32高级定时器(三)

    Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...

  10. Javascript进阶篇——(DOM—节点---插入、删除和替换元素、创建元素、创建文本节点)—笔记整理

    插入节点appendChild()在指定节点的最后一个子节点列表之后添加一个新的子节点.语法: appendChild(newnode) //参数: //newnode:指定追加的节点. 为ul添加一 ...