题目:http://poj.org/problem?id=2888

题意:给定n(n <= 10^9)颗珠子,组成一串项链,每颗珠子可以用m种颜色中一种来涂色,如果两种涂色方法通过旋转项链可以得到视为等价。

   然后再给定K组限制,每组限制a、b代表颜色a和颜色b不能涂在相邻的珠子上面。问一共有多少种涂色方法。

思路: 如果这题没有后面的限制,就和 poj 2154 一样了:http://www.cnblogs.com/jian1573/p/3234627.html

  现在我们要处理的就是 K 种限制, 可以用DP求解。 i为珠子编号, c为颜色编号那么:dp[i][c]=∑dp[i-1][cc]  cc 为可以与 c 相邻的颜色编号;

  由于N为 1e9 O(N) 会TLE, 所以我们可以用矩阵快速幂来优化为O(lgN):具体用m[i][j]=1,表示合法, m[i][j]=0表示不合法,

  那么m^k后的对角线上的元素和即为所求。

 #include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
const int Mod=;
int N, M, K, T;
struct Mar
{
int m[][];
inline void zero( ){
memset(m, , sizeof m);
}
inline void one( ){
zero( );
for( int i=; i<M; ++i ){
for( int j=; j<M; ++j ){
m[i][j]=;
}
}
}
inline void unit( ){
zero();
for( int i=; i<M; ++ i )
m[i][i]=;
}
inline Mar operator *(const Mar &a) const {
Mar C;C.zero();
for( int i=; i<M; ++i ){
for(int j=; j<M; ++j ){
for( int k=; k<M; ++k ){
C.m[i][j]+=m[i][k]*a.m[k][j];
C.m[i][j]%=Mod;
}
}
}
return C;
}
inline Mar operator ^ (int t) const{
Mar B=*this, C;
C.unit( );
while(t){
if(t&)C=C*B;
B=B*B;
t>>=;
}
return C;
}
}A;
int a[], p[],cntp=;
void getp( )
{
for( int i=; i<=1e5; ++ i ){
if( !a[i] )p[cntp++]=i;
for( int j=; j<cntp&&i*p[j]<1e5; ++ j ){
a[i*p[j]]=;
if( i%p[j]== )break;
}
}
} int Phi( int x )
{
int res=x;
for( int i=; i<cntp&&p[i]*p[i]<=x; ++i ){
if( x%p[i]== ){
res/=p[i]; res*=(p[i]-);
while(x%p[i]==){
x/=p[i];
}
}
}
if(x>){
res/=x;res*=(x-);
}
return res%Mod;
}
int P_M(int a, int b)
{
int res=;
while(b){
if(b&)res*=a, res%=Mod;
a*=a, a%=Mod;
b>>=;
}
return res; }
int work( int k )
{
Mar C=A^k;
int res=;
for( int i=; i<M; ++i )
res+=C.m[i][i];
return res;
}
int polya( )
{
int ans=;
for( int i=; i*i<=N; ++ i ){
if( N%i== ){
if(i*i==N){
ans+=Phi(i)*work(i);
ans%=Mod;
}
else{
ans+=Phi(i)*work(N/i);
ans%=Mod;
ans+=Phi(N/i)*work(i);
ans%=Mod;
}
}
}
return ans;
}
int main( )
{
getp();
scanf("%d", &T);
while (T--){
scanf("%d%d%d", &N, &M, &K);
A.one();
for( int i=, x, y; i<K; ++i ){
scanf("%d%d", &x, &y);
A.m[x-][y-]=A.m[y-][x-]=;
}
int ans=polya();
int inv=P_M(N%Mod, Mod-);
ans*=inv;ans%=Mod;
printf("%d\n", ans);
}
return ;
}

poj 2888 Magic Bracelet <polya定理>的更多相关文章

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

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

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

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

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

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

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

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

  5. 解题:POJ 2888 Magic Bracelet

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

  6. poj 2888 Magic Bracelet

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

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

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

  8. POJ 2888 Magic Bracelet ——Burnside引理

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

  9. poj 2154 Color【polya定理+欧拉函数】

    根据polya定理,答案应该是 \[ \frac{1}{n}\sum_{i=1}^{n}n^{gcd(i,n)} \] 但是这个显然不能直接求,因为n是1e9级别的,所以推一波式子: \[ \frac ...

随机推荐

  1. 远征(expedition)

    [题目描述] 寒枫将军将要带领他的部队去圣雪山消灭那里的冰龙. 部队分成了若干个小队,属于同一个小队的人兵种相同.寒枫将军有着杰出的指挥能力,在战斗的时候,寒枫将军能够让所有相同兵种的人互相配合,使t ...

  2. 免费CSS鼠标样式代码大全

    原文发布时间为:2008-08-01 -- 来源于本人的百度文章 [由搬家工具导入] http://5211.91.tc/sb.htm

  3. 学习javascript设计模式之代理模式

    1.代理模式为一个对象提供一个代用品或占位符,以便控制对它的访问. 2.不用代理模式: 客户 -> 本体  使用代理模式:  客户 -> 代理 -> 本体 3.例子场景1 点击操作与 ...

  4. 使用 IntelliJ IDEA 开发 Android 应用程序时配置 Allatori 进行代码混淆

    IntelliJ IDEA 提供了非常强大的 Android 开发支持,就连 Google 官方推荐的 Android Studio 其实也是 IntelliJ IDEA 的一个 Android 开发 ...

  5. 开发使用mysql的一些必备知识点整理(三)高级

    简介 实体与实体之间有3种对应关系,这些关系也需要存储下来 在开发中需要对存储的数据进行一些处理,用到内置的一些函数 视图用于完成查询语句的封装 事务可以保证复杂的增删改操作有效 关系 创建成绩表sc ...

  6. Java 异常处理的优劣

    Java编程中的异常处理是一个很常见的话题了,几乎任何一门介绍性的Java课程都会提到异常处理.不过,我认为很多人其实没有真正掌握正确处理异常情况的方法和策略,最多也就不过了解个大概,知道概念.我想对 ...

  7. 深入理解Thread构造函数

    上一篇快速认识线程 本文参考汪文君著:Java高并发编程详解. 1.线程的命名 在构造现成的时候可以为线程起一个名字.但是我们如果不给线程起名字,那线程会有一个怎样的命名呢? 这里我们看一下Threa ...

  8. 安装Vmware增强工具

    主机: Win7 虚拟机: VMware8.0+Debian6 目标: 离线安装软件包和VMware Tools 在虚拟机上安装完debian6后 1.在vmware的菜单中选择Vm->inst ...

  9. 邁向IT專家成功之路的三十則鐵律 鐵律二:IT專家專業之道–專精

    在IT技術的領域當中有許多的類別,若要細分那可真是難以一一列舉,但常見的大致有軟體研發工程師.韌體研發工程師.系統分析師.網路工程師.系統工程師.維護工程師.動畫設計師.製圖工程師.以及各類別的專業電 ...

  10. android 获取GPS定位

    AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xm ...