SDOI2015 序列統計

2022-03-16 22:59:51 字數 1128 閱讀 2384

有\(s\)個不同的數構成的序列(每個數可以使用任意次數),求有多少個不同的長度為\(n\)的序列,滿足它們的乘積在模\(m\)意義下為\(x\),答案對1004535809取模

設\(f(i,j)\)表示填了前\(i\)個數字,模\(m\)為\(j\)的方案數,推狀態轉移方程的時候可以發現第一維完全沒有必要一步一步走,即

\[f(i+j,c) = \prod_f(i,a)\times f(j,b)

\]可以運用類似快速冪的方法,將第一維壓成\(logn\),時間複雜度為\(o(m^2logn)\)

第二維是\(a+b=c\)就可以卷積了,考慮用原根將乘法變成加法,即\(a\times b = c,(mod\)

\(m)\)變成\(g^\equiv g^,(mod\)

\(m)\),進而有\(log_ga+log_gb\equiv log_gc,(mod\)

\(\varphi(m))\)

那麼對所有數取個\(log_g\),就可以在模\(\varphi(m)\)意義下進行加法卷積了

#include#define n 400005

using namespace std;

typedef long long ll;

const ll mod = 1004535809;

int n,m,x,s,mp[8005];

int r[n],len,l;

ll a[n],b[n];

ll p[n],q[n];

ll g=3,gi,inv,g;

template inline t max(t a,t b)

template inline t min(t a,t b)

template void read(t &x)

ll qp(ll a,ll b,ll mo)

int get_g(int m)

} if(x!=1&&x!=m-1) if(qp(i,(m-1)/x,m)==1) ok=0;

if(ok) return i;

} return -1;

}void ntt(ll *a,int opt)

cout<<(b[mp[x]]%mod+mod)%mod

}

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