HDU 2865 Birthday Toy
题意:n个小珠子组成的正n边形,中间有一个大珠子。有木棍相连的两个珠子不能有相同的颜色,旋转后相同视为相同的方案,求着色方案数。
\(\\\)
先选定一种颜色放在中间,剩下的\(k-1\)种颜色再摆在环上。下面直接令\(k=k-1\)。
根据Burnside引理,\(ans=\sum_{a|n}f(a)\phi(\frac{n}{a})\)。\(f(a)\)表示最多使用\(k\)种颜色且长度为\(a\)的,首尾以及相邻珠子颜色互不相同的方案数。计算\(f(n)\)时,假设\(n-1\)号珠子与\(1\)号珠子相同,则对答案的贡献为\((k-1)\cdot f(n-2)\);若不同,贡献为\((k-2)\cdot f(n-1)\)。所以\(f(n)=(k-1)\cdot f(n-2)+(k-2)\cdot f(n-1)\)。用矩阵快速幂就好了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 1000005
#define mod 1000000007
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
ll n,k;
int p[N];
bool vis[N];
void pre(int n) {
for(int i=2;i<=n;i++) {
if(!vis[i]) p[++p[0]]=i;
for(int j=1;j<=p[0]&&1ll*i*p[j]<=n;j++) {
vis[i*p[j]]=1;
if(i%p[j]==0) break;
}
}
}
int phi(int n) {
ll ans=n;
for(int i=1;1ll*p[i]*p[i]<=n;i++) {
if(n%p[i]==0) ans=(ans-ans/p[i]);
while(n%p[i]==0) n/=p[i];
}
if(n>1) ans=(ans-ans/n);
return ans;
}
struct matrix {
ll f[2][2];
void Init() {memset(f,0,sizeof(f));}
}tem,g,t;
matrix operator *(const matrix &a,const matrix &b) {
tem.Init();
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
(tem.f[i][j]+=a.f[i][k]*b.f[k][j])%=mod;
return tem;
}
matrix ksm(matrix g,int x) {
matrix ans;
ans.Init();
for(int i=0;i<2;i++) ans.f[i][i]=1;
for(;x;x>>=1,g=g*g)
if(x&1) ans=ans*g;
return ans;
}
ll ksm(ll t,ll x) {
ll ans=1;
for(;x;x>>=1,t=t*t%mod)
if(x&1) ans=ans*t%mod;
return ans;
}
ll cal(ll n) {
if(n==1) return 0;
matrix ans=t*ksm(g,n-2);
return ans.f[0][1];
}
int main() {
pre(1000000);
while(scanf("%lld%lld",&n,&k)!=EOF) {
g.f[0][0]=0,g.f[0][1]=k-2;
g.f[1][0]=1,g.f[1][1]=k-3;
t.f[0][0]=0,t.f[0][1]=(k-1)*(k-2)%mod;
ll ans=0;
for(int i=1,maxx=sqrt(n);i<=maxx;i++) {
if(n%i==0) {
(ans+=cal(i)*phi(n/i)%mod)%=mod;
if(i*i!=n) (ans+=cal(n/i)*phi(i)%mod)%=mod;
}
}
ans=ans*ksm(n,mod-2)%mod;
ans=ans*k%mod;
cout<<ans<<"\n";
}
return 0;
}
HDU 2865 Birthday Toy的更多相关文章
- HDU 2865 Birthday Toy [Polya 矩阵乘法]
传送门 题意: 相邻珠子不能相同,旋转等价.$n$个珠子$k$中颜色,求方案数 首先中间珠子$k$种选择,$k--$如果没有相邻不同的限制,就和$POJ\ 2154$一样了$|C(f)|=k^{\#( ...
- hdu 2865 Polya计数+(矩阵 or 找规律 求C)
Birthday Toy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 2865
和上题一样,但K较大,不能直接用矩阵来写.这个矩阵必定是这个形式的. 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 分成对角线上元素B与非对角线上元素A k: 1 2 3 4 ... ...
- hdu 2481 Toy
好题!!!没话说…… 用到的知识面很多,这题的难点在于公式的推导. 原始推导过程见:http://hi.baidu.com/spellbreaker/item/d8bb3bda5af30be6795d ...
- HDU 1007 Quoit Design(二分+浮点数精度控制)
Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- hdu 4052 线段树扫描线、奇特处理
Adding New Machine Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 1828 线段树扫描线(周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- hdu 4453 splay
Looploop Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- 随手练——HDU 1078 FatMouse and Cheese(记忆化搜索)
http://acm.hdu.edu.cn/showproblem.php?pid=1078 题意: 一张n*n的格子表格,每个格子里有个数,每次能够水平或竖直走k个格子,允许上下左右走,每次走的格子 ...
随机推荐
- thinkphp如何利用反射实现钩子方法
ThinkPHP框架的控制器模块是如何实现 前控制器.后控制器,及如何执行带参数的方法? PHP系统自带的 ReflectionClass.ReflectionMethod 类,可以反射用户自定义类的 ...
- 高并发连接导致打开文件过多:java.io.IOException: Too many open files 解决方法
用 CentOS 做 API 接口服务器供其他终端调用时,并发量高会报错:java.io.IOException: Too many open files. 其原因是在 Linux 下默认的Socke ...
- HTML XML 介绍
一. HTML(HyperTextMark-upLanguage)即超文本标记语言,是WWW的描述语言. 二. XML即ExtentsibleMarkup Language(可扩展标记语言), XML ...
- SpringBoot入门之集成Druid
Druid:为监控而生的数据库连接池.这篇先了解下它的简单使用,下篇尝试用它做多数据源配置.主要参考:https://github.com/alibaba/druid/wiki/常见问题 https: ...
- 数据库MongoDB
一.MongoDB简介 MongoDB是由c++语言编写的,是一个基于分布式文件存储的开源数据库系统,在高负载的情况下,添加更多的节点,可以保证服务器性能.MongoDB旨在为web应用提供扩展的高性 ...
- Infopath 2013 通过UserProfileService读取AD用户信息
我刚刚看过什么C#文章获得当前用户使用Web服务的详细信息. 其实无需编写任何代码,可以实现完全相同的结果.所以我在这里简单的介绍一下: *如果你已经熟悉这个,这个篇文章可以跳过. *此介绍是建立在I ...
- 使用Git Extensions简单入门Git
前言 关于这个主题,之前我录了段视频教程,在本地看清晰度还可以,但传到优酷上就很不清晰了,即使是后来重制后还是一样不清晰,所以现在想整理成文字版.当然,大家还可以将我百度云上的视频下载下来观看,连同优 ...
- [PHP] 算法-把数组排成最小的数的PHP实现
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 解法1 1.数组排序, ...
- Java 雇员管理小练习(理解面向对象编程)
在学习集合框架的时候,初学者很容易练习到学生管理系统.雇员管理体统等练习题.在学习集合框架之前,基本上Java基本语法都学完了,集合框架也从侧面的检验对前面学习的理解.下面用一个曾经做过的练习题,回顾 ...
- Java并发编程:线程池的使用(转载)
转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...