4818 Sdoi2017 序列計數

2021-07-30 14:35:42 字數 1985 閱讀 2568

4818: [sdoi2017]序列計數

time limit: 30 sec memory limit: 128 mb

submit: 396 solved: 267

[submit][status][discuss]

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 output

33 hint

source

鳴謝infinityedge上傳

[submit][status][discuss]

注意到題目中的

p 很小,那說明這麼大的

m是沒用的

用線性篩預處理

m 以內的素數

列舉每個數字,mo

dp之後記錄到乙個陣列裡面 記f

[i][

j]為前

i 個數字的和為

j的方案數

轉移顯然可以矩陣乘法

再統計乙個g[

i][j

] 含義相同,但是強制每個數字都是非素數 f[

n][0

]−g[

n][0

] 就是答案了

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int n = 100;

const

int maxm = 2e7 + 233;

const

int maxn = 1e6 + 3e5 + 233;

typedef

long

long ll;

typedef

unsigned

int u32;

const ll mo = 20170408;

int n,m,p,tot,c[n],d[n],pri[maxn];

u32 mi[32],not_pri[maxm / 32];

inline

void mark(int k)

inline

bool search(int k)

inline

int mul(const ll &x,const ll &y)

inline

int add(const

int &x,const

int &y)

inline

int dec(const

int &x,const

int &y)

struct data

data operator * (const data &b)

}f,g,f,g;

void ksm()

}int main()

}++c[1 % p]; ++d[1 % p];

for (int i = 0; i < p; i++)

for (int j = 0; j < p; j++)

ksm(); cout

<< dec(f.a[0][0],g.a[0][0]) << endl;

return

0;}

bzoj4818 SDOI2017 序列計數

題目鏈結 先考慮暴力 dp f i j 表示前 i 個數,數字之和模 p 餘 j 的方案數。我們先不考慮必須有質數這個條件,先統計出全部方案。然後再減去沒有質數的方案就行了。那麼就有 f i 1 j k p f i j 1 le k le m 然後發現這個其實並不需要 o m 的轉移,因為 j k ...

BZOJ4818 SDOI2017 序列計數

bzoj luogu alice想要得到乙個長度為 n 的序列,序列中的數都是不超過 m 的正整數,而且這 n 個數的和是 p 的倍數。alice還希望,這 n 個數中,至少有乙個數是質數。alice想知道,有多少個序列滿足她的要求。一行三個數,n,m,p 1 le n le 10 9,1 le m...

BZOJ 4818 Sdoi2017 序列計數

bzoj 4818 sdoi2017 序列計數 矩陣乘法 alice想要得到乙個長度為n的序列,序列中的數都是不超過m的正整數,而且這n個數的和是p的倍數。alice還希望 這n個數中,至少有乙個數是質數。alice想知道,有多少個序列滿足她的要求。一行三個數,n,m,p。1 n 10 9,1 m ...