博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 4818: [Sdoi2017]序列计数
阅读量:5164 次
发布时间:2019-06-13

本文共 1194 字,大约阅读时间需要 3 分钟。

Description

Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数。Alice还希望

,这n个数中,至少有一个数是质数。Alice想知道,有多少个序列满足她的要求。

Solution

补集转换

用没有质数限制的方案-一个质数都没有的方案

然后这个题是无序的,这样就非常好做了

\(f[i][j]\) 表示选 \(i\) 个数,和 \(\mod p=i\) 的方案数
\(f[i+1][(j+k)\mod P]=f[i][j]*g[k]\)
\(g[k]\) 表示 \(\mod P=k\) 的数的个数

矩阵快速幂优化一下即可

#include
using namespace std;const int N=2e7+10,mod=20170408;int n,m,P,prime[N],num=0;bool vis[N];void priwork(){ vis[1]=1; for(int i=2;i<=m;i++){ if(!vis[i])prime[++num]=i; for(int j=1;j<=num && i*prime[j]<=m;j++){ vis[i*prime[j]]=1; if(i%prime[j]==0)break; } }}struct mat{ int a[101]; mat(){memset(a,0,sizeof(a));} void clear(){memset(a,0,sizeof(a));} mat operator *(const mat &p){ mat ret; for(int i=0;i
>=1; }}int main(){ freopen("pp.in","r",stdin); freopen("pp.out","w",stdout); cin>>n>>m>>P; priwork(); mat S,T; S.a[0]=1; for(int i=1;i<=m;i++)T.a[i%P]++; ksm(S,T,n); int ans=S.a[0]; S.clear();T.clear();S.a[0]=1; for(int i=1;i<=m;i++)if(vis[i])T.a[i%P]++; ksm(S,T,n);ans=(ans-S.a[0]+mod)%mod; printf("%d\n",ans); return 0;}

转载于:https://www.cnblogs.com/Yuzao/p/8586503.html

你可能感兴趣的文章
inner join 各种连接 SQL语句
查看>>
经验人士的IOS APP设计心得
查看>>
teleport使用说明
查看>>
IdentityServer4 登录使用数据库
查看>>
从PDF中提取信息----PDFMiner
查看>>
极简Node教程-七天从小白变大神(一:你需要Express)
查看>>
Windows环境配置Apache+Mysql+PHP
查看>>
内网端口映射详解(花生壳)
查看>>
回调和回显有什么区别?
查看>>
业务逻辑与数据解耦+单元测试
查看>>
mysql数据备份
查看>>
Ural Timus 1009 K-based Numbers (dp+矩阵快速幂+快速乘)
查看>>
[经验总结] 从其它sheet页引用数据生成图表时没有图例的解决办法
查看>>
RabbitMQ(消息队列)私人学习笔记
查看>>
webApp开发
查看>>
Flask-Web开发(第一部分)
查看>>
程序猿,你也配吃10元的盒饭?
查看>>
zkw线段树模板练习。
查看>>
js生成随机数的方法实例总结
查看>>
C#小程序飞行棋地图绘制
查看>>