项链(burnside)
Description
有一个长度为 \(n\) 的项链,首尾相接形成环,现在你要给每一个位置一个颜色 \([1,m]\), 求所有不同的项链个数(可以通过旋转变成一样的称为相同)
Solution
根据 \(burnside\) 引理,答案为 \(\frac{1}{n}\sum_{i=1}^{|G|}c1_i\)
也就是枚举所有的置换,求不动点个数之和
置换一共有 \(n\) 种,分别为 \(1,2...n\)
枚举旋转的长度 \(i\) ,那么循环节的大小为 \(\frac{n}{gcd(i,n)}\) , 循环节个数为 \(gcd(i,n)\)
为什么?要使得 \(k*i \mod n=0\) ,那么 \(k*i\) 的最小值就是 \(lcm=\frac{i*n}{gcd(i,n)}\) ,所以 \(k\) 就等于 \(\frac{n}{gcd(i,n)}\) 了
那么要使得这个点为不动点(旋转 \(i\) 之后一模一样),那么同一循环节里面的点必须颜色相同
那么点的可以缩减为 \(gcd(i,n)\) 种
相当于问题转化为用 \(m\) 中颜色去覆盖 \(x=gcd(i,n)\) 个位置,我们设方案数为 \(calc(x,m)\)
转化为求 \(\sum_{i=1}^{n}calc(gcd(i,n),m)\)
枚举 \(gcd\)
答案就是 \(\sum_{i=1}^{n}calc(i)*phi[\lfloor\frac{n}{i}\rfloor]\)
\(calc\) 函数可以用矩乘求出
#include<bits/stdc++.h>
using namespace std;
template<class T>void gi(T &x){
int f;char c;
for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
}
const int N=1e7+10,mod=9973;
int prime[N],num=0,phi[N],n,K,m;bool vis[N];
inline void priwork(){
phi[1]=1;
for(int i=2,t;i<N;i++){
if(!vis[i])prime[++num]=i,phi[i]=i-1;
for(int j=1;j<=num && i*prime[j]<N;j++){
vis[t=i*prime[j]]=1;
if(i%prime[j])phi[t]=phi[i]*(prime[j]-1);
else {phi[t]=phi[i]*prime[j];break;}
}
}
}
inline int getphi(int x){
if(x<N)return phi[x];
int lim=sqrt(x),ret=x;
for(int i=1;i<=num && prime[i]<=lim;i++){
if(x%prime[i]==0){
ret=ret/prime[i]*(prime[i]-1);
while(x%prime[i]==0)x/=prime[i];
}
}
if(x>1)ret=ret/x*(x-1);
return ret;
}
struct mat{
int a[10][10];
inline void init(){memset(a,0,sizeof(a));}
inline mat operator *(const mat &p)const{
mat ret;
for(int i=0;i<m;i++)
for(int j=0;j<m;j++){
ret.a[i][j]=0;
for(int k=0;k<m;k++)
if(a[i][k] && p.a[k][j])
ret.a[i][j]=(ret.a[i][j]+a[i][k]*p.a[k][j])%mod;
}
return ret;
}
}S,T;
inline int calc(int x){
S.init();
for(int i=0;i<m;i++)S.a[i][i]=1;
mat D=T;x--;
while(x){
if(x&1)S=S*D;
D=D*D;x>>=1;
}
int ret=0;
for(int i=0;i<m;i++)
for(int j=0;j<m;j++)ret=(ret+S.a[i][j]*T.a[i][j])%mod;
return ret;
}
inline int qm(int x,int k){
int sum=1;if(x>=mod)x%=mod;
while(k){
if(k&1)sum=sum*x%mod;
x=x*x%mod;k>>=1;
}
return sum;
}
inline void work(){
int x,y;
cin>>n>>m>>K;
T.init();
for(int i=0;i<m;i++)for(int j=0;j<m;j++)T.a[i][j]=1;
for(int i=1;i<=K;i++){
gi(x);gi(y);x--;y--;
T.a[x][y]=T.a[y][x]=0;
}
int lim=sqrt(n),ans=0;
for(int i=1;i<=lim;i++){
if(n%i)continue;
ans=(ans+1ll*calc(i)*getphi(n/i))%mod;
if(i*i!=n)ans=(ans+1ll*calc(n/i)*getphi(i))%mod;
}
ans=ans*qm(n,mod-2)%mod;
cout<<ans<<endl;
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
priwork();
int T;cin>>T;
while(T--)work();
return 0;
}
项链(burnside)的更多相关文章
- 【BZOJ3202】项链(莫比乌斯反演,Burnside引理)
[BZOJ3202]项链(莫比乌斯反演,Burnside引理) 题面 BZOJ 洛谷 题解 首先读完题目,很明显的感觉就是,分成了两个部分计算. 首先计算本质不同的珠子个数,再计算本质不同的项链个数. ...
- P3307-[SDOI2013]项链【Burnside引理,莫比乌斯反演,特征方程】
正题 题目链接:https://www.luogu.com.cn/problem/P3307 题目大意 \(n\)个珠子的一个环形项链,每个珠子有三个\(1\sim k\)的整数. 两个珠子不同当且仅 ...
- 洛谷 P3307 - [SDOI2013]项链(Burnside 引理+数论)
题面传送门 看到题目我们显然可以将题目拆分成两部分:首先求出有多少个符合要求的珠子 \(c\),这样我们就可以将每种珠子看成一种颜色,题目也就等价于有多少种用 \(c\) 种颜色染长度为 \(n\) ...
- polya/burnside 学习
参考链接: http://www.cnblogs.com/hankers/archive/2012/08/03/2622231.html http://blog.csdn.net/raalghul/a ...
- bzoj 4330: JSOI2012 爱之项链
听说这题不公开.. 那就不贴题意了 首先要用burnside引理求出戒指的种数,那么对于一个顺时针旋转$k$个位置的置换就相当于连上一条$(i,(i+k)%R)$的边,每个环颜色必须相同 环的个数为$ ...
- bzoj3202:[Sdoi2013]项链
思路:首先考虑如何求珠子个数,一个珠子由a,b,c三个数组成且属于区间[1,a],并满足gcd(a,b,c)=1.由于要求本质相同,对于a,b,c这样的一个无序的数列且满足gcd(a,b,c)=1,设 ...
- HUST 1569(Burnside定理+容斥+数位dp+矩阵快速幂)
传送门:Gift 题意:由n(n<=1e9)个珍珠构成的项链,珍珠包含幸运数字(有且仅由4或7组成),取区间[L,R]内的数字,相邻的数字不能相同,且旋转得到的相同的数列为一种,为最终能构成多少 ...
- Burnside引理与Polya定理 学习笔记
原文链接www.cnblogs.com/zhouzhendong/p/Burnside-Polya.html 问题模型 有一个长度为 $n$ 的序列,序列中的每一个元素有 $m$ 种取值. 如果两个序 ...
- Invoker-n颜色涂m个珠子的项链
参考https://blog.csdn.net/anxdada/article/details/76862564. https://blog.csdn.net/baidu_35643793/artic ...
随机推荐
- 简单几步,提升.Net Core的开发效率
附加IIS进程调式? 以前在开发ASP.NET(MVC)项目的时候,为了加快程序的启动速度(调式),我们会选择使用IIS.先用IIS架设还在开发的项目,在需要调式的时候附加进程,而在更多时候,如果调整 ...
- 爬虫开发14.scrapy框架之分布式操作
分布式爬虫 一.redis简单回顾 1.启动redis: mac/linux: redis-server redis.conf windows: redis-server.exe redis-wi ...
- “全栈2019”Java第五十八章:多态中方法返回类型可以是子类类型
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- LoadRunner12_脚本中运行JavaScript
版权声明:本文为博主原创文章,未经博主允许不得转载. [系统及软件配置] LR版本:12.53 JDK版本:1.8 函数:web_js_run,该函数仅在LR12版本提供支持,LR11不支持JavaS ...
- ios 相机 自定义 相片的截取
前段时间公司需要做一个身份识别的功能,而系统相机无法满足要求,so自己自定义了. 上代码: .h文件 #import <UIKit/UIKit.h> #import <AVFound ...
- nginx高性能WEB服务器系列之九--nginx运维故障日常解决方案
nginx系列友情链接:nginx高性能WEB服务器系列之一简介及安装https://www.cnblogs.com/maxtgood/p/9597596.htmlnginx高性能WEB服务器系列之二 ...
- P4175 [CTSC2008]网络管理 树剖+树套树
$ \color{#0066ff}{ 题目描述 }$ M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通 ...
- 2016级算法第一次练习赛-C.斐波那契进阶
870 斐波那契进阶 题目链接:https://buaacoding.cn/problem/870/index 思路 通过读题就可以发现这不是一般的求斐波那契数列,所以用数组存下所有的答案是不现实的. ...
- 进阶篇:4.2)DFA设计指南:优化装配工序
本章目的:针对每一个装配工序,运用DFA进行优化. 1.前言 工序的优化在产品的精简之后. 这个是作者的实际做完DFA后得出的结论.原因倒是很简单,一个精密的产品,哪怕只是优化了一个零件,对整体的装配 ...
- 【算法笔记】B1045 快速排序
1045 快速排序 (25 分) 著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后 ...