P3702 [SDOI2017]序列计数

Posted mjtcn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3702 [SDOI2017]序列计数相关的知识,希望对你有一定的参考价值。

P3702 [SDOI2017]序列计数

链接

分析:

 

代码: 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==-)f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-0;return x*f;
}

const int N = 20000005, mod = 20170408;
int pri[N], n, m, p, tot;
bool nopri[N];

struct Poly{
    int a[105];
    Poly() { memset(a, 0, sizeof(a)); }
}A, B;
Poly operator * (const Poly &A, const Poly &B) {
    Poly C;
    for (int i = 0; i < p; ++i) 
        for (int j = 0; j < p; ++j) 
            (C.a[(i + j) % p] += (1ll * A.a[i] * B.a[j]) % mod) %= mod;
    return C;
}
void init(int n) {
    nopri[1] = true;
    for (int i = 2; i <= n; ++i) {
        if (!nopri[i]) pri[++tot] = i;
        for (int j = 1; j <= tot && pri[j] * i <= n; ++j) {
            nopri[i * pri[j]] = true;
            if (i % pri[j] == 0) break;
        }
    }
}
Poly ksm(Poly A,int b) {
    Poly res = A; b --;
    while (b) {
        if (b & 1) res = res * A;
        A = A * A;
        b >>= 1;
    }
    return res;
}
int main() {
    n = read(), m = read(); p = read();
    init(m);
    for (int i = 1; i <= m; ++i) {
        A.a[i % p] ++;
        if (nopri[i]) B.a[i % p] ++;
    }
    A = ksm(A, n); B = ksm(B, n);
    cout << (A.a[0] - B.a[0] + mod) % mod;
    return 0;
}

 

以上是关于P3702 [SDOI2017]序列计数的主要内容,如果未能解决你的问题,请参考以下文章

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

codevs 5964 [SDOI2017]序列计数

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

LibreOJ #2002. 「SDOI2017」序列计数

[Sdoi2017]序列计数

BZOJ4818: [Sdoi2017]序列计数