看cb做了这个题,我也做做吧,然后写了好几张草稿纸,才算推明白。
方法1:用特征方程,参考资料:https://wenku.baidu.com/view/3b3f8c04a6c30c2259019e22.html
方法2:用生成函数,参考资料:https://wenku.baidu.com/view/f4799f98370cba1aa8114431b90d6c85ec3a8807?pcf=2
https://rqy.moe/Algorithms/generating-function/
最后求出说有符合要求的素数的乘积。
参考代码:
这个代码效果一般,TLE
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans=1;
int n,m,p,t;
bool mp[300000007];
int pr[40000007],cnt;
//k=II(p)-1
void init() {//求出所有的质数并维护出质数积
for( int i=2; i<=n; ++i) {
if(!mp[i]) {
pr[++cnt]=i,(i&1)&&(ans=ans*i%p);
}
for(int j=1; i*pr[j]<=n; ++j) {
mp[i*pr[j]]=1;
if(i%pr[j]==0)break;
}
}
}
ll inv(ll x,int v) {
ll res=1;
while(v) {
if(v&1)res=res*x%p;
x=x*x%p,v>>=1;
}
return res;
}
int main() {
scanf(" %d %d %d",&n,&m,&p);
init();
while(m--) {
scanf(" %d",&t);
if(t==1) {
ans=-1;
break;
}
if(pr[t]==0)continue;
ans=ans*inv(pr[t],p-2)%p;//ans=ans/p[t]
pr[t]=0;//判重
}
if(ans!=-1)ans=(ans+p-1)%p;
printf("%lld\n",ans);
return 0;
}