BZOJ4818 [SDOI2017]序列计数 【生成函数 + 快速幂】
题目
Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数。Alice还希望
,这n个数中,至少有一个数是质数。Alice想知道,有多少个序列满足她的要求。
输入格式
一行三个数,n,m,p。
1<=n<=109,1<=m<=2×107,1<=p<=100
输出格式
一行一个数,满足Alice的要求的序列数量,答案对20170408取模。
输入样例
3 5 3
输出样例
33
题解
由题目中“至少一个是质数的条件”容易想到翻转一下,用总方案减去全是合数的方案
\(n\)个数凑出\(p\)的倍数,容易想到生成函数
我们构造一个生成函数\(G(x)\),第\(i\)次项的系数表示凑出模\(p\)意义下得\(i\)的数有多少种方案
显然我们枚举第一个数算出第一个\(G(x)\)的系数,只需要求出\(G(x)^n\),对应\(0\)项系数就是总方案
全是合数的方案,可以再构造一个生成函数\(F(x)\),只需要第一次枚举合数即可
甚至不用上fft,直接乘即可
\(O(m + p^2logn)\)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bitset>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 20000005,maxm = 100005,INF = 1000000000,P = 20170408;
bitset<maxn> isn;
int pr[maxn >> 1],pi,n,m,p;
void init(){
isn[1] = true;
for (int i = 2; i <= m; i++){
if (!isn[i]) pr[++pi] = i;
for (int j = 1; j <= pi && i * pr[j] <= m; j++){
isn[i * pr[j]] = true;
if (i % pr[j] == 0) break;
}
}
}
struct node{
LL a[105];
node(){memset(a,0,sizeof(a));}
}F,G;
inline node operator *(const node& a,const node& b){
node c;
for (int i = 0; i < p; i++)
for (int j = 0; j < p; j++){
int t = (i + j) % p;
c.a[t] = (c.a[t] + a.a[i] * b.a[j] % P) % P;
}
return c;
}
inline node operator ^(node a,LL b){
node ans;
ans.a[0] = 1;
for (; b; b >>= 1,a = a * a)
if (b & 1) ans = ans * a;
return ans;
}
LL qpow(LL a,LL b){
LL ans = 1;
for (; b; b >>= 1,a = a * a % P)
if (b & 1) ans = ans * a % P;
return ans;
}
int main(){
scanf("%d%d%d",&n,&m,&p);
init();
for (int i = 1; i <= m; i++){
F.a[i % p]++;
if (isn[i]) G.a[i % p]++;
}
node A = F^n,B = G^n;
LL ans;
ans = ((A.a[0] - B.a[0]) % P + P) % P;
cout << ans << endl;
return 0;
}
BZOJ4818 [SDOI2017]序列计数 【生成函数 + 快速幂】的更多相关文章
- [Sdoi2017]序列计数 [矩阵快速幂]
[Sdoi2017]序列计数 题意:长为\(n \le 10^9\)由不超过\(m \le 2 \cdot 10^7\)的正整数构成的和为\(t\le 100\)的倍数且至少有一个质数的序列个数 总- ...
- BZOJ.4818.[SDOI2017]序列计数(DP 快速幂)
BZOJ 洛谷 竟然水过了一道SDOI!(虽然就是很水...) 首先暴力DP,\(f[i][j][0/1]\)表示当前是第\(i\)个数,所有数的和模\(P\)为\(j\),有没有出现过质数的方案数. ...
- [BZOJ4818][SDOI2017]序列计数(动规+快速幂)
4818: [Sdoi2017]序列计数 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 972 Solved: 581[Submit][Status ...
- [bzoj4818][Sdoi2017]序列计数_矩阵乘法_欧拉筛
[Sdoi2017]序列计数 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=4818. 题解: 首先列出来一个递推式子 $f[i][0]$ ...
- 2019.02.11 bzoj4818: [Sdoi2017]序列计数(矩阵快速幂优化dp)
传送门 题意简述:问有多少长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数,且其中至少有一个数是质数,答案对201704082017040820170408取模(n≤1e9, ...
- BZOJ4818 [SDOI2017] 序列计数 【矩阵快速幂】
题目分析: 一个很显然的同类项合并.注意到p的大小最大为100,考虑把模p意义下相同的求出来最后所有的减去没有质数的做矩阵快速幂即可. 代码: #include<bits/stdc++.h> ...
- bzoj4818 [Sdoi2017]序列计数
Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望,这n个数中,至少有一个数是质数.Alice想知道,有多少个序 ...
- BZOJ4818 LOJ2002 SDOI2017 序列计数 【矩阵快速幂优化DP】*
BZOJ4818 LOJ2002 SDOI2017 序列计数 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数. Alice还希 ...
- 【BZOJ4818】[Sdoi2017]序列计数 DP+矩阵乘法
[BZOJ4818][Sdoi2017]序列计数 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ,这n个数 ...
随机推荐
- Redis的安装以及spring整合Redis时出现Could not get a resource from the pool
Redis的下载与安装 在Linux上使用wget http://download.redis.io/releases/redis-5.0.0.tar.gz下载源码到指定位置 解压:tar -xvf ...
- UIDeviceOrientation 和 UIInterfaceOrientation
有时候,我们处理自动布局时,需要获取到屏幕旋转方向: 以下为本人亲测: UIInterfaceOrientation: 我们需要在- (void)viewDidLoad或其他方法中添加观察者,检测屏幕 ...
- DD命令做备份和恢复
正确的备份方法是先挂载移动硬盘分区:mount /dev/sdb5 /mnt 然后再备份:dd if=/dev/sda of=/mnt/backup_sda.img 恢复时同样要先挂载,再恢复:mou ...
- C语言中声明和定义详解(待看。。
变量声明和变量定义 变量定义:用于为变量分配存储空间,还可为变量指定初始值.程序中,变量有且仅有一个定义. 变量声明:用于向程序表明变量的类型和名字. 定义也是声明,extern声明不是定义 定义也是 ...
- 八皇后问题(DFS)
题目描述: 要在国际象棋棋盘中放八个皇后,使任意两个皇后都不能互相吃,皇后能吃同一行.同一列,同一对角线上(两个方向的对角线)的任意棋子.现在给一个整数n(n<=92),输出前n种的摆法. 输入 ...
- 12Vim在系统配置中的应用示例
Vim 在系统配置中的应用示例 1. 配置主机名称 为了便于咱局域网中查找某台特定的主机,后者对主机进行区分,除了要有IP地址外,还要为主机配置一个主机名,主机名之间可以通过这个类似于域名的名称来相互 ...
- python数据类型之元组(tuple)
元组是python的基础类型之一,是有序的. 元组是不可变的,一旦创建便不能再修改,所以叫只读列表. name = ('alex', 'jack') name[0] = 'mark' # TypeEr ...
- poj 2376 选择工作区间问题 贪心算法
题意:给一些工作区间,如何选取最小的工作数量,覆盖[1,T]的工作时长 一开始的思路,当然也是错误的思路: 我想着,最小工作数量是吧?那肯定就是选择结束时间最晚的,给结束时间来一个排序.哎这个思路错误 ...
- isinstance() 函数
Python3 isinstance() 函数 描述 isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type(). isinstance() 与 type() 区别: t ...
- luogu3389 【模板】高斯消元法
#include <algorithm> #include <iostream> #include <cstdio> #include <cmath> ...