upd on 2021.1.7 更新了 ntt 做法:
不會\(\operatorname\),水乙個\(o(m^2\log n)\)的\(60pts\),大力卡常過的。
gmoj的時限是\(5s\),洛谷的時限\(1s\)完全過不了。
小c有乙個集合 \(s\),裡面的元素都是小於 \(m\) 的非負整數。他用程式編寫了乙個數列生成器,可以生成乙個長度為 \(n\) 的數列,數列中的每個數都屬於集合 \(s\)。
小c用這個生成器生成了許多這樣的數列。但是小c有乙個問題需要你的幫助:給定整數 \(x\),求所有可以生成出的,且滿足數列中所有數的乘積 \(\bmod \ m\) 的值等於 \(x\) 的不同的數列的有多少個。
小c認為,兩個數列 \(a\) 和 \(b\) 不同,當且僅當 \(\exists i \text a_i \neq b_i\)。另外,小c認為這個問題的答案可能很大,因此他只需要你幫助他求出答案對 \(1004535809\) 取模的值就可以了。
設\(f[i][j]\)表示選了\(2^i\)個數,乘積\(\bmod p\)之後的結果為\(j\)的方案數。
轉移顯然
\[f[k][l]=\sum^{}_f[k-1][i]\times f[k-1][j]
\]然後設\(n=\sum^_x_i2^i\),按照二進位制拆分計算方案數即可。
時間複雜度\(o(m^2\log n)\)。
利用矩陣乘法,同樣的思路複雜度為\(o(m^3\log n)\),期望得分\(30pts\)。
#pragma gcc optimize("ofast")
#pragma gcc optimize("inline") //卡常必備
#include #include #include #include using namespace std;
typedef long long ll;
const int n=8010,mod=1004535809/*,lg=30*/;
int n,p,m,t,cnt;
ll ans,f[50][n],g[50][n];
int main()
for (register int k=1;k<=lg;++k)
for (register int i=0;i=p) o-=p;
f[k][o]=(f[k][o]+f[k-1][i]*f[k-1][j])%mod;
}g[0][1]=1;
for (register int k=0;k<=lg;k++)
if (n&(1<=p) o-=p;
g[cnt][o]=(g[cnt][o]+g[cnt-1][i]*f[k][j])%mod;
}} printf("%lld\n",g[cnt][t]);
return 0;
}
BZOJ4403 序列統計
description 給定三個正整數n l和r,統計長度在1到n之間,元素大小都在l到r之間的單調不降序列的數量。輸出答案對10 6 3取模的結果。input 輸入第一行包含乙個整數t,表示資料組數。第2到第t 1行每行包含三個整數n l和r,n l和r的意義如題所述。output 輸出包含t行,...
BZOJ4403 序列統計
推導式子 baidu可得 設m r l 1 長度為i,元素大小在1 m之間的單調不降序列的數量有cm 1i m 1個 故答案為 n i 1 cm 1 i m 1 ni 1 cm 1i m 1 cm m 1 ni 2 cm 1i m 1 cm m 1 1 ni 3 cm 1i m 1 cm m 2 1...
BZOJ4403 序列統計
標籤 lucas定理,逆元 description 給定三個正整數n l和r,統計長度在1到n之間,元素大小都在l到r之間的單調不降序列的數量。輸出答案對10 6 3取模的結果。input 輸入第一行包含乙個整數t,表示資料組數。第2到第t 1行每行包含三個整數n l和r,n l和r的意義如題所述。...