题目链接

题意

求出 \(n\) 个珠子的在旋转同构意义下的手 个数,满足以下条件:

恰好有 \(m\) 个黑色珠子,其余为白色。

黑色珠子形成的最长连续段不能超过 \(k\) 个。

Sol

考虑 \(Burnside\) 引理\(/Polya\) 定理 , 那么答案就是:

\[\frac{\sum_{i=1}^n f(i)}{n}
\]

\(f(i)\) 表示在转 \(i\) 次的置换下所有合法染色方案中能够产生不动点的个数。这样我们就不用考虑旋转同构的问题了。

对于转 \(i\) 次的一个置换 , 显然它把这个长度为 n 的链分成了 \(gcd(n,i)\) 个环(也就是循环) , 那么一种方案要是不动点的话就必须满足这些环中的所有元素都是同色。

我们设 \(d=gcd(n,i)\) , 把式子再次变形:

\[ans=\frac{1}{n} \bigg( \sum_{d|n}^n F(d) \sum_{i=1}^{n}\boldsymbol[gcd(i,n)=d \boldsymbol]\bigg)
\]

这是个常见的式子了, \(n\) 中与 \(i\) 的 \(gcd\) 是 \(d\) 的数有 \(\varphi(\frac{n}{d})\) 个。

那么:

\[ans=\frac{1}{n} \bigg( \sum_{d|n}^n F(d) \varphi(\frac{n}{d}) \bigg)
\]

\(F(d)\)表示现在有 \(\frac{n}{d}\) 个循环 , 模\(d\)意义下在同一个剩余系中的珠子颜色要相同且黑色珠子不能有连续的超过 \(k\) 个 , 求合法的染色方案数。

因为当 \(d\) 确定下来的话 , 被分成的循环的情况也就确定了 , 模 \(d\) 相同的在一个环里。

既然这样 , 首先我们直接特判 \(n=m\) 的情况 , 这样由于染色的决策是一个循环的过程 , 每\(d\)个珠子之间就可以看作是互不影响了 , 于是就相当于我们现在有 \(d\) 个珠子 , 要给其中 \(\frac{m}{\frac{n}{d}}=\frac{md}{n}\) 个染成黑色 , 黑色段最长不能超过 \(k\) 个的合法方案数了。

由于是一个环直接做不好考虑首尾 , 所以直接枚举首尾总共已经有 \(i\) 个球被染色 , 那么我们就希望求出 \(Paint(n,m,k)\) 表示有 \(n\) 个球排成一列 , 首尾已经都是白色的 , 现在要给中间的球染成黑色,满足黑色段最长不超过 \(k\) 的方案数。

由于球是等价的 , 这样我们可以把原问题变成 现在有 \(n-m\) 个球 , 要在其中的 \(n-m-1\) 个空隙里插入 \(m\) 个球 , 要求每个空隙里不能插入超过 \(k\) 个球 , 求方案数。

这是一个简单的容斥问题了 , 我们枚举至少有多少个空隙插入了多余 \(k\) 个球 , 剩下的就隔板法求一个方案数就行了。这里复杂度只有 \(O(\frac{m}{k})\)

然后我们由于要枚举环首尾有多少个黑珠子 , 所以单次计算一个 \(F\) 的复杂度是 \(O(m)\) 的

但是注意这里的 \(m\) 不是原来的 \(m\) 它是 \(\frac{md}{n}\)

如果我们用 \(d'\) 来替换 \(\frac{n}{d}\) , 这样复杂度就是 \(O(\sum_{d'|n}\frac{m}{d'})\)

\(d'\) 还必须是 m的约数 , 所以显然我们的复杂度是 \(gcd(n,m)\) 的约数和 ,可以轻松通过。

#include<bits/stdc++.h>
#define Set(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=1e6+10;
const int mod=998244353;
template <typename T> inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}
typedef long long ll;
template <typename T>inline void Inc(T&x,int y){x+=y;if(x>=mod) x-=mod;return;}
template <typename T>inline void Dec(T&x,int y){x-=y;if(x < 0) x+=mod;return;}
template <typename T>inline int fpow(int x,T k){int ret=1;for(;k;k>>=1,x=(ll)x*x%mod) if(k&1) ret=(ll)ret*x%mod;return ret;}
int Sum(int x,int y){x+=y;if(x>=mod) return x-mod;return x;}
int Dif(int x,int y){x-=y;if(x < 0 ) return x+mod;return x;}
int n,m,k;
int gcd(int a,int b){return b? gcd(b,a%b):a;}
int pri[N],vis[N],cnt=0,phi[N],fac[N],finv[N];
inline int C(int n,int m){return n<m? 0:((ll)fac[n]*finv[m]%mod*finv[n-m]%mod);}
inline void Sieve(){
phi[1]=1;vis[1]=1;fac[0]=finv[0]=fac[1]=finv[1]=1;
int n=1e6;
for(int i=2;i<=n;++i) {
if(!vis[i]) pri[++cnt]=i,phi[i]=i-1;
fac[i]=(ll)fac[i-1]*i%mod;
for(int j=1;j<=cnt;++j){
int nt=i*pri[j];if(nt>n) break;
vis[nt]=1;
if(i%pri[j]==0) {phi[nt]=phi[i]*pri[j];break;}
phi[nt]=phi[i]*phi[pri[j]];
}
}
finv[n]=fpow(fac[n],mod-2);
for(int i=n-1;i;--i) finv[i]=(ll)finv[i+1]*(i+1)%mod;
return;
}
inline int Solve(int n,int m,int k){
if(!m) return 1;
++k;int mx=m/k;int ans=0;
for(int i=0;i<=mx;++i) {
int ret=m-i*k;
int res=(ll)C(n,i)*C(n+ret-1,n-1)%mod;
if(i&1) Dec(ans,res);else Inc(ans,res);
}
return ans;
}
inline int Calc(int n,int m){
int ret=0;int ed=min(m,k);
for(int i=0;i<=ed;++i) Inc(ret,(ll)(i+1)*Solve(n-m-1,m-i,k)%mod);
return ret;
}
int main()
{
Sieve();init(n),init(m),init(k);
if(n==m) {puts((k>=n)? "1":"0");return 0;}
int ans=0;
for(int i=1;i*i<=n;++i) {
if(n%i==0) {
if((m*i%n)==0) Inc(ans,(ll)Calc(i,m*i/n)*phi[n/i]%mod);
if(n/i!=i&&m%i==0) Inc(ans,(ll)Calc(n/i,m/i)*phi[i]%mod);
}
}
ans=(ll)ans*fpow(n,mod-2)%mod;
printf("%d\n",ans);
return 0;
}

最新文章

  1. [debian]SublimeText>PrettyCode無效
  2. R语言简单实现聚类分析计算与分析(基于系统聚类法)
  3. 解决Ubuntu下Sublime Text 3无法输入中文
  4. mongodb的分布式集群(4、分片和副本集的结合)
  5. GCC编译器入门
  6. bzoj1662: [Usaco2006 Nov]Round Numbers 圆环数
  7. (转)ManyToMany注解
  8. Python爬虫从入门到放弃(十九)之 Scrapy爬取所有知乎用户信息(下)
  9. php基础函数
  10. 【BZOJ4012】开店(主席树)
  11. 华硕ASUSPRO P5440UA笔记本电脑安装驱动
  12. linux随机字符串
  13. Kubernetes 1.3.1 快速单机部署
  14. vim相关
  15. Kivy 中文教程 实例入门 简易画板 (Simple Paint App):3. 随机颜色及清除按钮
  16. Solidworks如何打开swb文件
  17. VB高效导入Excel2003和Excel2007文件到MSHFlexGrid控件显示
  18. 将jar包安装到maven仓库
  19. 强悍的javascript手势库
  20. 2017 Multi-University Training Contest - Team 1—HDU6040

热门文章

  1. C#中winform下利用ArcEngine调用ArcGIS Server发布的服务 AE 10
  2. Openstack_单元测试工具 tox
  3. EncodeError: &#39;latin-1&#39; codec can&#39;t encode characters in position 69-70: ordinal not in range(256)
  4. Jmeter之线程组(Stepping和Ultimate)
  5. python调用c/c++时传递结构体参数
  6. 中国MOOC_零基础学Java语言_第3周 循环_1奇偶个数
  7. C 语言的运算符
  8. Excel表格数据导入MySQL数据库
  9. Cocos2d-X网络编程(1) 网络基本概念
  10. CF 686D. Kay and Snowflake