time limit: 30 sec
memory limit: 128 mb
submit: 673
solved: 327 [
submit][
status][
discuss]
小c有乙個集合s,裡面的元素都是小於m的非負整數。他用程式編寫了乙個數列生成器,可以生成乙個長度為n的數列,數列中的每個數都屬於集合s。
小c用這個生成器生成了許多這樣的數列。但是小c有乙個問題需要你的幫助:給定整數x,求所有可以生成出的,且滿足數列中所有數的乘積mod m的值等於x的不同的數列的有多少個。小c認為,兩個數列和不同,當且僅當至少存在乙個整數i,滿足ai≠bi。另外,小c認為這個問題的答案可能很大,因此他只需要你幫助他求出答案mod 1004535809的值就可以了。
一行,四個整數,n、m、x、|s|,其中|s|為集合s中元素個數。第二行,|s|個整數,表示集合s中的所有元素。
一行,乙個整數,表示你求出的種類數
mod 1004535809
的值。
4 3 1 2
1 28
【樣例說明】
可以生成的滿足要求的不同的數列有(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)。
【資料規模和約定】
對於10%的資料,1<=n<=1000;
對於30%的資料,3<=m<=100;
對於60%的資料,3<=m<=800;
對於全部的資料,1<=n<=109,3<=m<=8000,m為質數,1<=x<=m-1,輸入資料保證集合s中元素不重複
round 1 感謝yts1999上傳
ntt第一題
首先可以發現1004535809=479*2^21+1,而且是乙個質數,所以可以用ntt解決。
用f[i][j]表示i個數模m等於g^j的方案數(i為2的整數次冪,g為m的原根),則f[i][j]=∑f[i/2][k]*f[i/2][j-k]。這樣就成了卷積形式,ntt搞定。但n並不一定是2的整數次冪,這裡就要用到快速冪的思想(詳見**)。
#include#include#include#include#include#include#define f(i,j,n) for(int i=j;i<=n;i++)
#define d(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 40000
#define mod 1004535809
using namespace std;
int n,m,num,s,mg,g,bit,inv;
int a[maxn],c[maxn],a[maxn],b[maxn],ind[maxn],rev[maxn];
inline int read()
while (ch>='0'&&ch<='9')
return x*f;
}inline ll power(ll x,int y,int p)
inline bool get_order(int x,int m)
if (power(x,phi/i,m)==1)
} return true;
}inline int get_primitive_root(int x)
inline void ntt(int *a,int flag)
bzoj3992 SDOI2015 序列統計
不好做不好做,真心不好做。這個題顯然是dp,一開始我們這樣設計狀態f i j 表示長度為i的序列,積在模 m 意義下等於 j的數列的方案數。那顯然直接做的複雜度是o nm2 到了這裡,有一種矩陣快速冪做法,可以直接優化到o nm3 應該能過30 顯然正解不允許帶有o m3 所以矩陣肯定是不行了。到這...
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的不同的數列的有多...