SDOI2015 序列統計 (NTT)

2021-10-19 04:09:42 字數 3184 閱讀 7804

小c有乙個集合s,裡面的元素都是小於m的非負整數。他用程式編寫了乙個數列生成器,可以生成乙個長度為n的數列,數列中的每個數都屬於集合s。小c用這個生成器生成了許多這樣的數列。

但是小c有乙個問題需要你的幫助:給定整數x,求所有可以生成出的,且滿足數列中所有數的乘積mod m的值等於x的不同的數列的有多少個。

小c認為,兩個數列和不同,當且僅當至少存在乙個整數i,滿足ai≠bi。另外,小c認為這個問題的答案可能很大,因此他只需要你幫助他求出答案mod 1004535809的值就可以了。

input

一行,四個整數,n、m、x、|s|,其中|s|為集合s中元素個數。

第二行,|s|個整數,表示集合s中的所有元素。

1<=n<=10^9,3<=m<=8000,m為質數

0<=x<=m-1,輸入資料保證集合s中元素不重複x∈[1,m-1]

集合中的數∈[0,m-1]

output

一行,乙個整數,表示你求出的種類數mod 1004535809的值。

sample input

4 3 1 2

1 2sample output

8【樣例說明】

可以生成的滿足要求的不同的數列有(1,1,1,1)、(1,1,2,2)、(1,2,1,2)、(1,2,2,1)、

(2,1,1,2)、(2,1,2,1)、(2,2,1,1)、(2,2,2,2)

設f [i

][j]

f[i][j]

f[i][j

]:表示選了i

ii個數的乘積%m=

j\%m=j

%m=j

的方案數

f [i

<

<1]

[j]=

∑(j1

×j2)

%m=j

f[i]

[j1]

×f[i

][j2

]f[i<<1][j]=\sum_f[i][j_1]\times f[i][j_2]

f[i<

<1]

[j]=

(j1​

×j2​

)%m=

j∑​f

[i][

j1​]

×f[i

][j2

​]乘法目前來說是超越知識

那麼將相乘轉化為指數上的相加,暴艹出m

mm的原根

題目保證了m

mm是質數,一定會有原根

f [i

<

<1]

[j]=

∑(j1

+j2)

%m=j

f[i]

[j1]

×f[i

][j2

]f[i<<1][j]=\sum_f[i][j_1]\times f[i][j_2]

f[i<

<1]

[j]=

(j1​

+j2​

)%m=

j∑​f

[i][

j1​]

×f[i

][j2

​]這就長得很像可以卷積的玩意兒

涉及取模那就用ntt

nttnt

t但是這個跟普通的式子下面的條件略有不同j1+

j2=j

j_1+j_2=j

j1​+j2

​=j[m−

1,2m

−2

][m-1,2m-2]

[m−1,2

m−2]

這裡面也會對答案有貢獻,被m−1

m-1m−

1取模

#

include

#include

#include

using

namespace std;

#define

intlong

long

#define

mod1004535809

#define

maxn

20000

int g, len =

1, inv;

int r[maxn]

, ans[maxn]

, f[maxn]

, fi[maxn]

;int

qkpow

(int x,

int y,

int mod )

return ans;

}void

ntt(

int*c,

int f )}}

if( f ==-1

)}void

root

(int m )}if

( x >1&&

qkpow

( i, phi / x, m )==1

)continue;if

( flag )}}

signed

main()

int l =0;

while

( len <=

(( m -1)

<<1)

) inv =

qkpow

( len, mod -

2, mod )

;for

(int i =

0;i < len;i ++

) r[i]

=( r[i >>1]

>>1)

|(( i &1)

<<

( l -1)

);ans[0]

=1;while

( n )

ntt( f,1)

;for

(int i =

0;i < len;i ++

) f[i]

= f[i]

* f[i]

% mod;

ntt( f,-1

);for(

int i = m -

1;i < len;i ++

) f[i %

( m -1)

]=( f[i %

( m -1)

]+ f[i]

)% mod, f[i]=0

; n >>=1;

}printf

("%lld\n"

, ans[fi[x]])

;return0;

}

SDOI2015 序列統計

time limit 30 sec memory limit 128 mb submit 1829 solved 870 submit status discuss 小c有乙個集合s,裡面的元素都是小於m的非負整數。他用程式編寫了乙個數列生成器,可以生成乙個長度為n的數 列,數列中的每個數都屬於集合...

SDOI2015 序列統計

description 小c有乙個集合s,裡面的元素都是小於m的非負整數。他用程式編寫了乙個數列生成器,可以生成乙個長度為n的數列,數列中的每個數都屬於集合s。小c用這個生成器生成了許多這樣的數列。但是小c有乙個問題需要你的幫助 給定整數x,求所有可以生成出的,且滿足數列中所有數的乘積mod m的值...

SDOI2015 序列統計

點此看題 第一次寫ntt text ntt,被搞自閉了。0x01 樸素dp 設f i j f i j f i j 為選i ii個數乘積為j jj的方案數,轉移如下 f 2 i j f i k f i j inv k f 2i j f i k times f i j times inv k f 2i ...