[bzoj4818][Sdoi2017]序列计数

来自FallDream,未经允许,请勿转载,谢谢。


 Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数。Alice还希望,这n个数中,至少有一个数是质数。Alice想知道,有多少个序列满足她的要求。答案取模20170408

n<=10^9 m<=2*10^7 p<=100

题解:考虑计算任意选择的答案 然后把质数去掉,再算一次答案,求差即可。

然后这道题数据范围好水啊 p只有100  瞎矩阵乘法都能过 那个要k^3logn

当然,直接生成函数快速幂也是一样的 只有k^2logn 基本就是模板了

然后我就不知道怎么继续优化了 模数太奇怪没法ntt  而且数据只有100说不准常数一大跑的还没k^2快

#include<iostream>
#include<cstdio>
#include<cstring>
#define mod 20170408
using namespace std;
inline int read()
{
    int x = 0; char ch = getchar();
    while(ch < ‘0‘ || ch > ‘9‘)ch = getchar();
    while(ch >= ‘0‘ && ch <= ‘9‘){x = x * 10 + ch - ‘0‘;ch = getchar();}
    return x;
}

int n,m,p,a[205],b[205],s[mod],num=0,c[205],d[205],C[205];
bool mark[mod];

void mul(int*A,int*B)
{
    memset(C,0,sizeof(C));
    for(register int i=0;i<p;i++)
        for(register int j=0;j<p;j++)
            C[i+j]=(C[i+j]+1LL*A[i]*B[j])%mod;
    for(int i=p-1;i>=0;i--) A[i]=C[i]+C[i+p];
}

int main()
{
    n=read();m=read();p=read();
    for(register int i=0;i<p;i++) a[i]=b[i]=m/p+(m%p>=i)-(i==0);
    for(register int i=2;i<=m;i++)
    {
        if(!mark[i]) s[++num]=i,--b[i%p];
        for(register int j=1;s[j]*i<=m;j++)
        {
            mark[s[j]*i]=1;
            if(i%s[j]==0) break;
        }
    }
    for(c[0]=d[0]=1;n;n>>=1,mul(a,a),mul(b,b))
        if(n&1) mul(c,a),mul(d,b);
    printf("%d\n",(c[0]-d[0]+mod)%mod);
    return 0;
}
时间: 2024-10-11 01:07:50

[bzoj4818][Sdoi2017]序列计数的相关文章

[bzoj4818][Sdoi2017]序列计数_矩阵乘法_欧拉筛

[Sdoi2017]序列计数 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=4818. 题解: 首先列出来一个递推式子 $f[i][0]$表示$i$个任意数的答案. $f[i][1]$表示$i$个合数的答案. 转移的时候发现可以用矩阵优化这个过程. 至于怎么把矩阵建出来,我们可以开个桶来解决这个问题. 代码: #include <bits/stdc++.h> using namespace std; typedef long lon

【BZOJ4818】[Sdoi2017]序列计数 DP+矩阵乘法

[BZOJ4818][Sdoi2017]序列计数 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ,这n个数中,至少有一个数是质数.Alice想知道,有多少个序列满足她的要求. Input 一行三个数,n,m,p. 1<=n<=10^9,1<=m<=2×10^7,1<=p<=100 Output 一行一个数,满足Alice的要求的序列数量,答案对20170408取模. Sampl

[Sdoi2017]序列计数

4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 317  Solved: 210 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ,这n个数中,至少有一个数是质数.Alice想知道,有多少个序列满足她的要求. Input 一行三个数,n,m,p. 1<=n<=10^9,1<=m<=2×10^7,1<

P3702 [SDOI2017]序列计数

P3702 [SDOI2017]序列计数 链接 分析: 代码: #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<cctype> #include<set> #include<queue> #include<vector> #include<map

【bzoj4818】 Sdoi2017—序列计数

http://www.lydsy.com/JudgeOnline/problem.php?id=4818 (题目链接) 题意 一个长度为$n$的序列,每个元素是不超过$m$的正整数,且这$n$个数的和是$p$的倍数,这$n$个数中至少有一个是质数,问这样的序列有多少个. Solution md吓死我了,还以为想错了,$p^2\log n$的半天不敢写=.= $f[i][j]$表示忽略质数条件下的长度为$i$,和$mod~p=j$的序列数:$g[i][j]$表示满足没有一个数是质数的情况下长度为$

【bzoj4818】[Sdoi2017]序列计数 矩阵乘法

原文地址:http://www.cnblogs.com/GXZlegend/p/6825132.html 题目描述 Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望,这n个数中,至少有一个数是质数.Alice想知道,有多少个序列满足她的要求. 输入 一行三个数,n,m,p. 1<=n<=10^9,1<=m<=2×10^7,1<=p<=100 输出 一行一个数,满足Alice的要求的序列数量,答案对2017

BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法

Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ,这n个数中,至少有一个数是质数.Alice想知道,有多少个序列满足她的要求. Input 一行三个数,n,m,p. 1<=n<=10^9,1<=m<=2×10^7,1<=p<=100 Output 一行一个数,满足Alice的要求的序列数量,答案对20170408取模. Sample Input 3 5 3 Sample Outp

BZOJ 4818 SDOI2017 序列计数

刚出炉的省选题,还是山东的. 自古山东出数学和网络流,堪称思维的殿堂,比某地数据结构成风好多了. 废话不说上题解. 1.题面 求:n个数(顺序可更改),值域为[1,m],和为p的倍数,且这些树里面有质数的方案数是多少? 解题报告: 0% O(n^n)爆搜,没什么好讲的,用来拍DP: #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #define LL

codevs 5964 [SDOI2017]序列计数

 [题解] 官方题解就两句话. 写了三个版本的不同分值代码.看代码吧. 前导1 //f[i][j][1/0]表示长为i,sum mod p=j,是否已经选了质数的方案数 #include<cstdio> using namespace std; const int mod=20170408; const int N=1e6+1; int tot,prime[N/3];bool check[N]; int n,m,f[2][N][2];int p; void pre(){ n=1e6;check