题目: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. 金鹰教程网 FLASH8.0(AS)视频教程(下载地址)自认为最好的一个Flash教程

    原文发布时间为:2008-07-29 -- 来源于本人的百度文章 [由搬家工具导入] 可以用迅雷新建批量任务下载,很方便的。 金鹰教程网 FLASH8.0教学视频 到目前(2008年7月29日21:2 ...

  2. IC 拔取器 rework station

  3. React-Native Navigator-this.props.navigation....

    render() { return ( <View> <Text>2</Text> <Button title = "跳转到指定的页面" ...

  4. nrm+nvm

    一.nvm的安装和使用   nvm全称Node Version Manager是 Nodejs 版本管理器,它让我们能方便的对 Nodejs 的版 本进行切换. nvm 的官方版本只支持 Linux ...

  5. java retry:详解

    发现 今天在探秘线程池原理知识点,在阅读JDK源码时遇到程序代码中出现如下代码,因为之前没有遇到过,于是特地记录下来并谷歌了一番,后面我自己做了一些简要的验证和分析. 验证 网上溜达一番发现,这ret ...

  6. Spring Boot中使用AOP记录请求日志

    这周看别人写的springboot后端代码中有使用AOP记录请求日志,以前没接触过,因此学习下. 一.AOP简介 AOP为Aspect Oriented Programming的缩写,意为:面向切面编 ...

  7. Java方法中传值和引用传递的问题(转)

    说明:标题其实说法是错误的.Java中只有值传递,没有引用传递. ... ... //定义了一个改变参数值的函数 public static void changeValue(int x) { x = ...

  8. 【ActiveMQ】2.spring Boot下使用ActiveMQ

    在spring boot下使用ActiveMQ,需要一下几个条件 1.安装并启动了ActiveMQ,参考:http://www.cnblogs.com/sxdcgaq8080/p/7919489.ht ...

  9. Android开发——内存优化 图片处理

    8.  用缓存避免内存泄漏 很常见的一个例子就是图片的三级缓存结构,分别为网络缓存,本地缓存以及内存缓存.在内存缓存逻辑类中,通常会定义这样的集合类. private HashMap<Strin ...

  10. vuejs npm chromedriver 报错

    vuejs npm chromedriver 报错   # 全局安装 vue-cli$ npm install -g vue-cli# 创建一个基于 "webpack" 模板的新项 ...