第一眼,Burnside 直接丢上去啊。

设 \(f(n,m)\) 是有 \(n-m\) 个白色珠子和 \(m\) 个白色珠子的满足题意的环的个数,容易得到答案是:

\[\sum_{d|n,d|m}f(\frac{n}{d},\frac{m}{d})\varphi(d)
\]

考虑左边这个 \(f\) 怎么做。

我们将环断开,枚举前缀和后缀的黑色珠子个数,有:

\[f(n,m)=\sum_{x+y\leq k,x+y+2\leq n}g(n-x-y-1,m-x-y)=\sum_{i=0}^{\min(k,n-2)}(i+1)\times g(n-i-1,m-i)
\]

其中 \(g(n,m)\) 为不存在超过 \(k\) 个连续黑色珠子的序列个数,且序列的最后一个元素是白色的。

我们似乎可以接受单次 \(O(n\log n)\) 计算 \(f\) 的算法。

考虑上生成函数。我们强制钦定每一段黑珠子后面跟上一个白珠子(包括 \(0\) 个白珠子),那么一段的 OGF 就是 \(\sum_{i=0}^{k}x^i=\frac{1-x^{k+1}}{1-x}\)。

\(g\) 的单点就是 \(g(n,m)=[x^m](\frac{1-x^{k+1}}{1-x})^{n-m}\)。

写开:

\[g(n,m)=[x^m]\frac{1}{(1-x)^{n-m}}\times(1-x^{k+1})^{n-m}
\]
\[[x^m](\sum \binom{i+n-m-1}{i})\times(\sum_{i=0}^{n-m}\binom{n-m}{i}x^{(n-m)(k+1)})
\]

注意到你在单次处理时,这个 \(n-m\) 是一直不会变的。变的是多项式取哪一项。

直接把这两个东西写开,卷一下就好了。

我们再观察一下:

设 \(F(x)=\frac{1-x^{k+1}}{1-x}\)。

\[[x^m]\sum_{i=0}^k(i+1)x^iF^{n-m-1}(x)
\]
\[[x^m](xF'(x)+F(x))F^{n-m-1}(x)
\]
\[[x^m]xF'(x)F^{n-m-1}(x)+F^{n-m}(x)
\]
\[([x^{m-1}]F'(x)F^{n-m-1}(x))+([x^m]F^{n-m}(x))
\]
\[(\frac{1}{n-m}[x^{m-1}](F^{n-m}(x))')+([x^m]F^{n-m}(x))
\]
\[(\frac{m}{n-m}[x^m]F^{n-m}(x)))+([x^m]F^{n-m}(x))
\]
\[\frac{n}{n-m}[x^m]F^{n-m}(x)
\]

右边简单。

\[[x^m]\frac{(1-x^{k+1})^{n-m}}{(1-x)^{n-m}}
\]
\[[x^m](\sum_{i=0}\binom{i+n-m-1}{i}x^i)(\sum_{i=0}^{n-m}\binom{n-m}{i}(-1)^{i}x^{i(k+1)})
\]
\[\sum_{i=0}^{n-m}\binom{n-m}{i}(-1)^i\binom{m-i(k+1)+n-m-1}{n-m-1}
\]

然后就能够线性求单点的 \(f\) 了。

#include<cstdio>
const int M=1e5+5,mod=998244353;
int n,m,k,fac[M],ifac[M];
inline int pow(int a,int b){
int ans(1);for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;return ans;
}
inline int C(const int&n,const int&m){
return 1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
inline int phi(int n){
int ans(1);
for(int i=2;i<=n;++i)if(!(n%i)){
ans*=i-1;n/=i;while(!(n%i))ans*=i,n/=i;
}
return ans;
}
inline int f(const int&n,const int&m){
int ans(0);
for(int i=0;i<=n-m;++i){
if(m-i*(k+1)<0)break;
if(i&1)ans=(ans+1ll*(mod-C(n-m,i))*C(m-i*(k+1)+n-m-1,n-m-1))%mod;
else ans=(ans+1ll*C(n-m,i)*C(m-i*(k+1)+n-m-1,n-m-1))%mod;
}
return 1ll*n*pow(n-m,mod-2)%mod*ans%mod;
}
signed main(){
int ans(0);
scanf("%d%d%d",&n,&m,&k);
if(n==m)return printf("%d",m<=k),0;
fac[0]=fac[1]=ifac[0]=ifac[1]=1;
for(int i=2;i<=n;++i)fac[i]=1ll*fac[i-1]*i%mod,ifac[i]=1ll*(mod-mod/i)*ifac[mod%i]%mod;
for(int i=2;i<=n;++i)ifac[i]=1ll*ifac[i-1]*ifac[i]%mod;
for(int i=1;i<=n;++i)if(!(n%i)&&!(m%i))ans=(ans+1ll*f(n/i,m/i)*phi(i))%mod;
printf("%d",1ll*ans*pow(n,mod-2)%mod);
}

最新文章

  1. .NET Core手记 - Json.NET的使用
  2. java.lang.UnsatisfiedLinkError: Couldn&#39;t load vi_voslib from loader dalvik.system.PathClassLoader
  3. iOS耳机操作
  4. 安装DirectX SDK (June 2010) 失败(Error Code S1023)(转)
  5. PowerDesigner 表视图修改
  6. 1154 能量项链[区间dp]
  7. ASCII 字符代码表
  8. UVA 11865 Stream My Contest(最小树形图)
  9. Python中通过Image的open之后,去show结果打不开bmp图片,无法正常显示图片
  10. Java基础知识强化32:String类之String类的判断功能
  11. C#.NET利用ContextBoundObject和Attribute实现AOP技术--AOP事务实现例子
  12. Java学习之道:Java项目打包发布
  13. Installing perl and writing your first perl program in Ubuntu
  14. 使用alembic进行数据库版本管理
  15. C++中所有的变量和函数都必须有类型
  16. [算法总结] 13 道题搞定 BAT 面试——字符串
  17. CNN学习入门
  18. phpcs
  19. oracle 12c AUTO_SAMPLE_SIZE动态采用工作机制
  20. IBM MQ 集成CXF 发送JMS 消息

热门文章

  1. 手势仿QQ侧滑---秀清
  2. 通过示例学习PYTORCH
  3. jqGrid 修改单元格值或者替换图片及其他
  4. 蟒蛇书学习笔记——Chapter 09 Section 01 创建和使用类
  5. gpg 使用入门
  6. Git修改提交历史中的作者及邮箱信息
  7. tarjan2
  8. centos安装MySQL问题
  9. 操作系统发展史 &amp; 进程
  10. Spring AOP应用之一:声明式事务