有\(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 ...