萌新刚学逆元 TLE 了两个求助
查看原帖
萌新刚学逆元 TLE 了两个求助
673585
thrznb666楼主2023/8/11 21:24
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int qread(){
	int x=0;char ch;bool f=0;
	while((ch=getchar())&&(ch>'9'||ch<'0')) if(ch=='-') f=1;x=(ch^48);
	while((ch=getchar())&&(ch>='0'&&ch<='9')) x=x*10+(ch^48);
	return f?-x:x;
}
const int Maxn=5e6+7;
int n,inv[Maxn],p,k,ans;
int B1,B2,pre[Maxn],suf[Maxn];
int a[Maxn];
struct frac{
	int a,b;
	frac(int a=0,int b=0):a(a),b(b){}
}s[Maxn];
inline void init(void){
	B1=pow(p,1.0/3);
	B2=B1*B1;
	inv[1]=1;for(int i=2;i<=p/B1;i++) inv[i]=1ll*(p-p/i)*inv[p%i]%p;
	s[0]=frac(0,1);s[B2]=frac(1,1);
	pre[B2]=suf[B2]=B2;
	for(int i=2;i<=B1;i++)
		for(int j=1;j<i;j++){
			int pos=1ll*j*B2/i;
			if(pre[pos]) continue;
			pre[pos]=suf[pos]=pos;
			s[pos]=frac(j,i);
		}
	for(int i=1;i<=B2;i++) if(!pre[i]) pre[i]=pre[i-1];
	for(int i=B2;i;i--) if(!suf[i]) suf[i]=suf[i+1];
}
inline int calc(int T,frac x){
	ll pos=1ll*T*x.b;
	if(abs(pos-1ll*p*x.a)>p/B1) return -1;
	pos%=p;
	if(pos<=p/B1) return 1ll*x.b*inv[pos]%p;
	return p-1ll*x.b*inv[p-pos]%p;
}
inline int Getinv(int x){
	if(x<=p/B1) return inv[x];
	ll pos=1ll*x*B2/p,res=calc(x,s[pre[pos]]);
	if(res==-1) res=calc(x,s[suf[pos]]);
	return res;
}
int main(){
	//freopen("P5431_1.in","r",stdin);
	n=qread(),p=qread(),k=qread();
	for(int i=1;i<=n;i++) a[i]=qread();
	init();
	ll kkk=k;
	for(int i=1;i<=n;i++){
		ans=(ans+1ll*kkk*Getinv(a[i])%p)%p;
		kkk=kkk*k%p;
	}
	printf("%d",ans%p);
	return 0;
}

2023/8/11 21:24
加载中...