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