序列计数(count)

Portal -->broken qwq

Description

??  ?给你一个长度为\(n\)的序列,序列中的每个数都是不超过\(m\)的正整数,求满足以下两个条件的序列数量:

1.序列中至少有一个质数

2.序列中\(n\)个数之和为\(p\)的倍数

??  ?数据范围:\(1<=n<=10^9,1<=m<=2*10^7,1<=p<=100\)

Solution

??  ?我的妈呀真实智力康复。。为什么连最基础的矩乘优化都忘了==

??  ?记\(f[i][j]\)表示前\(i\)个数和模\(p\)为\(j\)的答案,然后转移我们矩乘一下就好了

?  ?至于必须满足其中一个数是质数,我们考虑容斥,先算出所有的,然后再把所有的素数去掉再算一遍转移矩阵,然后再算一次答案两个相减就好了

??  ?然而如果像我一开始一样弱智写了个\(n^3\)矩乘只能拿\(50\)

??  ?这题实际上可以直接\(f[i+1][(j+k)\%p]=f[i][j]*f[i][k]\)就完事了,所以只要\(n^2\)就好了,真实智力康复qwq

?  ?

??  ?代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int M=2*(1e7)+10,MOD=20170408;
int add(int x,int y){return (1LL*x+y)%MOD;}
int mul(int x,int y){return 1LL*x*y%MOD;}
int n,m,p,Ans1,Ans2,cnt;
struct Mtrix{/*{{{*/
    int a[110];
    int n;
    void init(int _n){n=_n;memset(a,0,sizeof(a));}
    void setUnit(int _n){init(_n);a[0]=1;}
    friend Mtrix operator * (Mtrix &x,Mtrix &y){
        int tmp;
        Mtrix ret;
        ret.init(x.n);
        for (int i=0;i<ret.n;++i)
            for(int j=0;j<ret.n;++j){
                tmp=(i+j)%p;
                ret.a[tmp]=add(ret.a[tmp],mul(x.a[i],y.a[j]));
            }
        return ret;
    }
}ori,ret,base,ans1,ans2,tmp;/*}}}*/
bool vis[M];
int P[1500000];
int get_pos(int x,int y){return (x-y+p)%p;}
void fill(int op){
    int tmp;
    ori.init(p);
    for (int i=1;i<=m;++i){
        if (op==1&&!vis[i]) continue;
        ori.a[i%p]=add(ori.a[i%p],1);
    }
}
void ksm(int y){
    ret.setUnit(p); base=ori;
    for (;y;y>>=1,base=base*base)
        if (y&1) ret=ret*base;
}
void prework(int n){
    cnt=0;
    vis[1]=1;
    for (int i=2;i<=n;++i){
        if (!vis[i])
            P[++cnt]=i;
        for (int j=1;j<=cnt&&P[j]*i<=n;++j){
            vis[i*P[j]]=true;
            if (i%P[j]==0)
                break;
        }
    }
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
#endif
    scanf("%d%d%d",&n,&m,&p);
    prework(m);
    fill(0);
    ksm(n);
    Ans1=ret.a[0];

    fill(1);
    ksm(n);
    Ans2=ret.a[0];
    printf("%d\n",(Ans1-Ans2+MOD)%MOD);
}

原文地址:https://www.cnblogs.com/yoyoball/p/9439387.html

时间: 2024-10-22 03:53:39

序列计数(count)的相关文章

[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<

AC日记——「SDOI2017」序列计数 LibreOJ 2002

「SDOI2017」序列计数 思路: 矩阵快速幂: 代码: #include <bits/stdc++.h> using namespace std; #define mod 20170408 #define ll long long struct MatrixType { int n,m; ll ai[105][105]; void mem(int n_,int m_) { n=n_,m=m_; for(int i=0;i<=n;i++) for(int v=0;v<=m;v++

LibreOJ #2002. 「SDOI2017」序列计数

二次联通门 : LibreOJ #2002. 「SDOI2017」序列计数 /* LibreOJ #2002. 「SDOI2017」序列计数 线性筛 + 矩阵优化dp 先构造出全部情况的矩阵 用矩阵快速幂计算答案 再构造出全不是质数的矩阵 计算出答案 前一个答案减后一个答案即可 */ #include <cstdio> #include <iostream> #include <cstring> const int BUF = 12312312; char Buf[BU

【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

P3702 [SDOI2017]序列计数

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

luogu3702-[SDOI2017]序列计数

Description Alice想要得到一个长度为nn的序列,序列中的数都是不超过mm的正整数,而且这nn个数的和是pp的倍数. Alice还希望,这nn个数中,至少有一个数是质数. Alice想知道,有多少个序列满足她的要求. 输入输出格式 输入格式: 一行三个数,n,m,p. 输出格式: 一行一个数,满足Alice的要求的序列数量,答案对20170408取模. 输入输出样例 输入样例#1: 3 5 3 输出样例#1: 33 说明 对20%的数据,1≤n,m≤100 对50%的数据,1≤m≤

[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

DTOJ #3160. 序列计数(count)

[题目描述] Alice想要得到一个长度为 $n$ 的序列,序列中的数都是不超过 $m$ 的正整数,而且这 $n$ 个数的和是 $p$ 的倍数. Alice还希望,这 $n$ 个数中,至少有一个数是质数. Alice想知道,有多少个序列满足她的要求. [输入格式] 一行三个数, $n,m,p$. [输出格式] 一行一个数,满足Alice的要求的序列数量.由于满足条件的序列可能很多,输出结果对 $20170408$ 取模. [样例] 样例输入 3 5 3 样例输出 33 [数据范围与提示] 对于

STL_算法_元素计数(count、count_if)

C++ Primer 学习中... 简单记录下我的学习过程 (代码为主) count . count_if #include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<set> #include<algorithm> using namespace std; /*********************** count count_if