CRT+LUCAS+EX欧拉 古代猪文

求这个东西
在这里插入图片描述
指数取模,想到欧拉定理,注意到模数是个比底数大的质数,底数和模数肯定是互质的,并且模数是个指数, m m m的欧拉函数值就是 m − 1 m-1 m1。那么 a b   m o d   m a^b \bmod m abmodm等价于 a b   m o d   m − 1   m o d   m a^{b \bmod m-1}\bmod m abmodm1modm
在这里插入图片描述

于是转化为求 b   m o d   m − 1 b \bmod m-1 bmodm1,现在的问题是 m − 1 m-1 m1不是质数了,但它可以分解成几个质数的一次方,这种取模一般就考虑先分别求出对每个质因子的余数,然后用中国剩余定理,就能求出来对原模数的余数。
在这里插入图片描述

那么下一步的问题是怎么求出来 b   m o d   f a c i b \bmod fac_i bmodfaci,也就是求出来指数对于每个质因子的余数,注意到质因子不大,并且指数是个组合数求和,考虑 l u c a s lucas lucas定理
在这里插入图片描述

需要注意的是,求一个质因子的余数时, l u c a s lucas lucas的模数都是固定的,只用预处理一次

long long CRT(vi& W,vi& B,int k/*方程组数*/){
	long long x,y,a=0,m,n=1;
	for(long long i=0;i<k;i++) n*=W[i];
	for(long long i=0;i<k;i++){
		m=n/W[i];
		a=(a+B[i]*m%n*power(m,W[i]-2,W[i])%n)%n;
	}
	return a>0?a:a+n;
}
vi fa(N);
void init(int n,int p){
	fa[0]=1;
	rep(i,1,n){
		fa[i]=fa[i-1]*i%p;
	}
}
int lucas(int n,int m,int p){
	auto C=[&](int n,int m,int p)->int{
		if(n<m)return 0;
		return fa[n]*power(fa[m],p-2,p)%p*power(fa[n-m],p-2,p)%p;
	};
	auto &&lu=[&](auto &&lu,int n,int m,int p)->int{
		if(n<m)return 0;
		if(m==0)return 1;	
		return C(n%p,m%p,p)*lu(lu,n/p,m/p,p)%p;
	};
	return lu(lu,n,m,p);
}
void solve() {
    int n,g;
    cin>>n>>g;
    vi d={2,3,4679,35617};
    vi r;
    int mod=999911659;
    rep(i,0,3){
    	init(d[i],d[i]);
    	int sum=0;
		rep(j,1,sqrt(n)){
			if(n%j==0){
				sum+=lucas(n,j,d[i]);
				sum%=d[i];
				if(n/j!=j){
					sum+=lucas(n,n/j,d[i]);
					sum%=d[i];
				}
			}
		}
		r.push_back(sum);
	}
	int res=CRT(d,r,4);
	cout<<power(g,res,mod);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值