日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Luogu P3321 [SDOI2015]序列统计

發布時間:2025/3/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Luogu P3321 [SDOI2015]序列统计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[SDOI2015]序列統計

題目描述

小C有一個集合\(S\),里面的元素都是小于\(M\)的非負整數。他用程序編寫了一個數列生成器,可以生成一個長度為\(N\)的數列,數列中的每個數都屬于集合\(S\)。小C用這個生成器生成了許多這樣的數列。但是小C有一個問題需要你的幫助:給定整數\(x\),求所有可以生成出的,且滿足數列中所有數的乘積\(mod M\)的值等于\(x\)的不同的數列的有多少個。小C認為,兩個數列\({A_i}\)\({B_i}\)不同,當且僅當至少存在一個整數i,滿足\(A_i≠B_i\)。另外,小C認為這個問題的答案可能很大,因此他只需要你幫助他求出答案\(mod \ 1004535809\)的值就可以了。

輸入輸出格式

輸入格式:

一行,四個整數,\(N、M、x、|S|\),其中\(|S|\)為集合S中元素個數。第二行,\(|S|\)個整數,表示集合\(S\)中的所有元素。

輸出格式:

一行,一個整數,表示你求出的種類數\(mod\ 1004535809\)的值。

輸入輸出樣例

輸入樣例#1:

復制

4 3 1 2 1 2

輸出樣例#1:

復制

8

說明

【樣例說明】

可以生成的滿足要求的不同的數列有(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\le N\le 1000\)

對于30%的數據,\(3\le M\le 100\)

對于60%的數據,\(3\le M\le 800\)

對于全部的數據,\(1\le N\le 10^9,3\le M\le 8000,M為質數,1\le x\le M-1\),輸入數據保證集合\(S\)中元素不重復

我們構造函數\(A(x)=\sum_{i}[i\in S]x^i\),答案就是\(A\)自卷\(N\)次過后第\(x\)項的系數。

不過這個卷積不太尋常:\(\displaystyle c(x)=\sum_{i=1}^M\sum_{j=1}^M[i*j\% M==x]\cdot a(i)\cdot b(j)\)

除法非常難處理,于是我們考慮轉化為我們熟悉的加法。將乘法轉化為加法,很容易就想到質數函數。我們設冪為\(g\),則\(g^{a*b}=g^a+g^b\)。我們對于沒個數\(i\),我們取\(x\)為它的代表元,滿足\(g^x\%M==i\)

考慮選取原根\(g\),因為\(g^x\)\(x\in[1,M-1]\)時兩兩不同。

于是我們將0舍去,然后就可以將乘法卷積轉化為加法卷積了。具體實現要用到快速冪,每次卷積一次后,要將下標\(x\ge M-1\)的部分的值累加在\(x-(M-1)\)下標的位置上。

代碼:

#include<bits/stdc++.h> #define ll long long #define MAXM 8005 #define mod 1004535809 using namespace std; inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}int n,m,x,num; ll ksm(ll t,ll x,ll M) {ll ans=1;for(;x;x>>=1,t=t*t%M)if(x&1) ans=ans*t%M;return ans; }ll Find(ll m) {if(m==2) return 1;for(int i=2;i<=m-1;i++) {int flag=1;for(int j=2;j*j<m;j++) {if(ksm(i,(m-1)/j,m)==1) {flag=0;break;}}if(flag==1) return i;} }int id[MAXM]; int rev[MAXM<<2]; void NTT(ll *a,int d,int flag) {static const ll G=3;int n=1<<d;for(int i=0;i<n;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<d-1);for(int i=0;i<n;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);for(int s=1;s<=d;s++) {int len=1<<s,mid=len>>1;ll w=flag==1?ksm(G,(mod-1)/len,mod):ksm(G,mod-1-(mod-1)/len,mod);for(int i=0;i<n;i+=len) {ll t=1;for(int j=0;j<mid;j++,t=t*w%mod) {ll u=a[i+j];ll v=t*a[i+j+mid]%mod;a[i+j]=(u+v)%mod;a[i+j+mid]=(u-v+mod)%mod;}}}if(flag==-1) {ll inv=ksm(n,mod-2,mod);for(int i=0;i<n;i++) a[i]=a[i]*inv%mod;} }ll a[MAXM<<2]; ll f[MAXM<<2],ans[MAXM<<2]; void mul(ll *a,ll *b,int d) {for(int i=0;i<(1<<d);i++) a[i]=a[i]*b[i]%mod;NTT(a,d,-1);for(int i=0;i<m-1;i++) (a[i]+=a[i+m-1])%=mod,a[i+m-1]=0; }void ksm(int k) {ans[0]=1;int d=ceil(log2(m*2));for(;k;k>>=1) {if(k&1) {NTT(ans,d,1),NTT(f,d,1);mul(ans,f,d);NTT(f,d,-1);}NTT(f,d,1);mul(f,f,d);} }int main() {n=Get(),m=Get(),x=Get(),num=Get();ll g=Find(m);ll now=1;for(int i=0;i<m-1;i++) {id[now]=i;now=now*g%m;}int a;for(int i=1;i<=num;i++) {a=Get();if(a) f[id[a]]=1;}ksm(n);cout<<ans[id[x]];return 0; }

轉載于:https://www.cnblogs.com/hchhch233/p/10048336.html

總結

以上是生活随笔為你收集整理的Luogu P3321 [SDOI2015]序列统计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。