比赛 4043级2023省选模拟赛9 评测结果 AAAAAAAAAA
题目名称 序列统计 最终得分 100
用户昵称 op_组撒头屯 运行时间 0.922 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2023-03-30 11:18:54
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define clr(f,n) memset(f,0,sizeof(ll)*(n))
#define cpy(f,g,n) memcpy(f,g,sizeof(ll)*(n))
const int N=16384;
const ll mod=1004535809;
const ll _G=3;
const ll invg=334845270;
int k,m,x,s;
int tn=0,tr[N<<1],ln[N];
int getg(){
    for (int i=1;i<m;i++){
        int now=1;
        for (int j=1;j<m;j++){
            (now*=i)%=m;
            if (now==1){
                if (j==m-1)return i;
                else break;
            }
        }
    }
}
void init(){
    int g=getg();
    ln[1]=0;int now=1;
    for (int i=1;i<m;i++){
        (now*=g)%=m;ln[now]=i;
    }
}
void tpre(int n){
    if (n==tn)return ;tn=n;
    for (int i=0;i<n;i++)tr[i]=(tr[i>>1]>>1)|((i&1)?n>>1:0);
}
ll fst(ll x,ll y){
    ll ans=1;
    while(y){
        if (y&1)ans=ans*x%mod;
        x=x*x%mod;y>>=1;
    }return ans;
}
void NTT(ll *g,int n,bool opt){
    tpre(n);
    static ll f[N<<1],w[N<<1]={1};
    for (int i=0;i<n;i++)f[i]=g[tr[i]];
    for (int p=2;p<=n;p<<=1){
        int len=p>>1;
        ll tG=fst(opt?_G:invg,(mod-1)/p);
        for (int i=1;i<len;i++)w[i]=w[i-1]*tG%mod;
        for (int i=0;i<n;i+=p){
            for (int j=i;j<i+len;j++){
                ll now=f[j+len]*w[j-i]%mod;
                f[j+len]=(f[j]+mod-now)%mod;
                f[j]=(f[j]+now)%mod;
            }
        }
    }
    if (opt)for (int i=0;i<n;i++)g[i]=f[i];
    else{
        ll invn=fst(n,mod-2);
        for (int i=0;i<n;i++)g[i]=f[i]*invn%mod;
    }
}
void px(ll *f,ll *g,int n){
    for (int i=0;i<n;i++)f[i]=f[i]*g[i]%mod;
}
void times(ll *f,ll *g,int len,int lim){
    int n=1;for (;n<=len;n<<=1);
    static ll sav[N<<1];
    clr(sav,n);cpy(sav,g,n);
    NTT(f,n,1);NTT(sav,n,1);
    px(f,sav,n);NTT(f,n,0);
    clr(sav,n);clr(f+lim,n-lim);
}
void upd(ll *f,ll *g,int len){
    int n=1;for (;n<=len;n<<=1);
    times(f,g,2*n,2*len);
    for (int i=0;i<len;i++)f[i]=(f[i]+f[i+len])%mod;
    clr(f+len,2*n-len);
}
ll id[N<<1],ans[N<<1];
int main(){
	freopen ("sdoi2015_sequence.in","r",stdin);
	freopen ("sdoi2015_sequence.out","w",stdout);
	scanf("%d%d%d%d",&k,&m,&x,&s);
	init();
	for (int i=1;i<=s;i++){
	    int t;scanf("%d",&t);
	    if (!t)continue;
	    id[ln[t]%(m-1)]=1;
    }
    ans[0]=1;
    while(k){
        if (k&1)upd(ans,id,m-1);
        upd(id,id,m-1);k>>=1;
    }
    printf("%lld\n",ans[ln[x]%(m-1)]);
}