洛谷P6197 [EER1]禮物 歐拉篩+生成函數

看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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章