bzoj3992 SDOI2015 序列統計

2021-07-30 21:52:33 字數 1403 閱讀 1288

不好做不好做,真心不好做。

這個題顯然是dp,一開始我們這樣設計狀態f[

i][j

] 表示長度為i的序列,積在模

m 意義下等於

j的數列的方案數。

那顯然直接做的複雜度是o(

nm2)

,到了這裡,有一種矩陣快速冪做法,可以直接優化到o(

nm3)

,應該能過30%。

顯然正解不允許帶有o(

m3) ,所以矩陣肯定是不行了。

到這裡可能就需要原根了,求出原根,每個數都能表示成原根的冪,這樣就可以用指數代替數,f[

i][j

] 表示長度為

i ,乘積在模

m意義下等於原根的

j 次冪的方案數。

這樣轉移就成了f[

i][j

]→f[

i][j

+kmo

dm−1

],顯然這就是多項式卷積,把f[

i]看做乙個多項式,它的

j 次項乘以另乙個多項式上

k次項上的乙個1,這個乘積會加到結果的第j+

k 次項上去。

很蛋疼的地方在於取模,不取模還好,取模怎麼做。其實也沒啥,每次求完卷積之後肯定會多出來一些不合法的,即它們的下標大於m−

1 ,這個時候只需要把的值加到合法的位置就好了,意思就是f[

imod

m−1]

←f[i

] 。

顯然多項式卷積滿足交換律,所以只需要把用來轉移的那個多項式進行快速冪。

總的時間複雜度o(

mlog

mlog

n)

//dp+ntt

#include

#include

#include

#define maxn 131072

#define mod 1004535809ll

#define ll long long

using namespace std;

ll up, n, m, s[maxn], r[maxn], trans[maxn], f[maxn], inv, tmp[maxn], ans[maxn],

tmp1[maxn], tmp2[maxn], x, pr;

inline ll pow(ll a, ll b, ll p)

void ntt(ll *a, ll n, ll opt)

}if(opt==-1)

}inline void juan(ll *a, ll *b, ll *c)

inline void pow(ll *a, ll b)

}void init()

void work()

}int main()

bzoj3992 SDOI2015 序列統計

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

bzoj3992 SDOI2015 序列統計

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

BZOJ3992 SDOI2015 序列統計

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