BZOJ 1951 SDOI2010 古代猪文 数论 Lucas定理

题目大意:给定N,G,求

首先由欧拉定理易知当A与p互质时A^B %p=A^(B%φ(p) ) %p

这里p是一个质数 于是φ(p)=p-1=999911658

然后由于这个数不是质数 难以处理 我们将它分解质因数 然后对于每个质因数的解用中国剩余定理合并即可

然后就是999911658有一个很好的性质 999911658=2*3*4679*35617 每个质因数的次数都是1次

于是我们可以套用卢卡斯定理 预先处理出对于每个质因数的阶乘和阶乘的逆元即可

注意此题有个细节 就是欧拉定理中a与p必须互质 而当a=0(即G=p)时gcd(a,p)=p

所以有一组数据是专门卡这个地方的 这组数据是999911659 999911657 取模后是0^0 于是得到1 但是答案是0

于是我们做一些处理 A^B %p=A^(B%φ(p)+φ(p) ) %p

这样就没问题了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Mo 999911659
#define Phi_Mo 999911658
using namespace std;
typedef long long ll;
typedef pair<ll,ll> abcd;
ll prime[4]={2,3,4679,35617};
ll n,g,ans[5];
ll factorial[4][35617],inverse[4][35617];
void Linear_Shaker(ll p,ll fac[],ll inv[])
{
	ll i;
	fac[0]=1;
	for(i=1;i<p;i++)
		fac[i]=fac[i-1]*i%p;
	inv[1]=1;
	for(i=2;i<p;i++)
		inv[i]=(p-p/i)*inv[p%i]%p;
	inv[0]=1;
	for(i=1;i<=p;i++)
		inv[i]=inv[i]*inv[i-1]%p;
}
ll C(ll n,ll m,ll p,ll fac[],ll inv[])
{
	if(n<m) return 0;
	if(n<p&&m<p)
		return fac[n]*inv[m]%p*inv[n-m]%p;
	return C(n%p,m%p,p,fac,inv)*C(n/p,m/p,p,fac,inv)%p;
}
inline void Calculate(ll x)
{
	int i;
	for(i=0;i<4;i++)
	{
		ans[i]+=C(n,x,prime[i],factorial[i],inverse[i]);
		ans[i]%=prime[i];
	}
}
abcd EXGCD(ll x,ll y)
{
	if(!y) return abcd(1,0);
	abcd temp=EXGCD(y,x%y);
	return abcd(temp.second,temp.first-x/y*temp.second);
}
ll Chinese_Remainder_Theorem()
{
	int i;
	ll re=0;
	for(i=0;i<4;i++)
	{
		abcd temp=EXGCD( Phi_Mo/prime[i] , prime[i] );
		ll x=(temp.first%Phi_Mo*(Phi_Mo/prime[i])%Phi_Mo+Phi_Mo)%Phi_Mo;
		re+=x*ans[i]%Phi_Mo;
		re%=Phi_Mo;
	}
	return re;
}
ll Quick_Power(ll x,ll y)
{
	ll re=1;
	while(y)
	{
		if(y&1)re*=x,re%=Mo;
		x*=x,x%=Mo;
		y>>=1;
	}
	return re;
}
int main()
{

	//freopen("1951.in","r",stdin);
	//freopen("1951.out","w",stdout);

	ll i;
	for(i=0;i<4;i++)
		Linear_Shaker(prime[i],factorial[i],inverse[i]);
	cin>>n>>g;
	for(i=1;i*i<n;i++)
		if(n%i==0)
			Calculate(i),Calculate(n/i);
	if(i*i==n)
		Calculate(i);
	ans[4]=Chinese_Remainder_Theorem();
	ans[4]=Quick_Power(g%Mo,ans[4]+Phi_Mo);
	cout<<ans[4]<<endl;
}
时间: 2024-08-11 03:16:00

BZOJ 1951 SDOI2010 古代猪文 数论 Lucas定理的相关文章

[BZOJ 1951][Sdoi2010]古代猪文(Lucas+CRT+费马小定理)

Description “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国.猪王国地理位置偏僻,实施的是适应当时社会的自给自足的庄园经济,很少与外界联系,商贸活动就更少了.因此也很少有其他动物知道这样一个王国. 猪王国虽然不大,但是土地肥沃,屋舍俨然.如果一定要拿什么与之相比的话,那就只能是东晋陶渊明笔下的大家想象中的桃花源了.猪

bzoj 1951 [Sdoi2010]古代猪文(数论知识)

Description “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国.猪王国地理位置偏僻,实施的是适应当时社会的自给自足的庄园经济,很少与外界联系,商贸活动就更少了.因此也很少有其他动物知道这样一个王国. 猪王国虽然不大,但是土地肥沃,屋舍俨然.如果一定要拿什么与之相比的话,那就只能是东晋陶渊明笔下的大家想象中的桃花源了.猪

bzoj 1951: [Sdoi2010]古代猪文

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #define ll long long 6 #define mul 999911659 7 using namespace std; 8 int n,g,a[4]; 9 int sh[4]={2,3,4679,35617},C1[4][35618]; 10 void exgcd(int a1,int

bzoj 1951: [Sdoi2010]古代猪文 【中国剩余定理+欧拉定理+组合数学+卢卡斯定理】

首先化简,题目要求的是 \[ G^{\sum_{i|n}C_{n}^{i}}\%p \] 对于乘方形式快速幂就行了,因为p是质数,所以可以用欧拉定理 \[ G^{\sum_{i|n}C_{n}^{i}\%\varphi(p)} \] \[ G^{\sum_{i|n}C_{n}^{i}\%p-1} \] 因为p-1不是质数,所以把它质因数分解为2,3,4679,35617,最后用中国剩余定理合并即可. #include<iostream> #include<cstdio> using

1951: [Sdoi2010]古代猪文|数论大合集

做这个题大概需要直到以下姿势:快速幂,费马小定理,卢卡斯定理,中国剩余定理.(大概也就这些 题目大概是让求 g∑d|nCdnmodp 然后根据费马小定理原式 =g∑d|nCdnmod(p?1)modp 然后也就是要求指数上的这个东西 ∑d|nCdnmod(p?1) 然后p?1还不是质数..需要分解成质因子然后用中国剩余定理合并,然后还要求组合数还要卢卡斯定理,最后特判一下g=p的情况 #include<algorithm> #include<iostream> #include&l

1951: [Sdoi2010]古代猪文

1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 2171  Solved: 904[Submit][Status][Discuss] Description “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国.猪王国地理位置偏僻,实施的是适应当时

【BZOJ】1951[Sdoi2010]古代猪文

[算法]欧拉定理+组合数取模(lucas)+中国剩余定理(CRT) [题解]给定G,N 先考虑简化幂运算,因为模数为素数,由欧拉定理可知G^k=G^(k%φ(p)) mod p,显然G^(k%φ(p)) mod p可以用快速幂求解 此时观察到2p>max(n)>p,所以可能n=p,此时不满足n,p互素,答案直接为0. 对于幂取模部分,因为p是素数,φ(p)=p-1,p-1=999911658=2*3*4679*35617. 由于lucas定理要求p为素数,所以用套路:分开求解后用中国剩余定理合

bzoj千题计划323:bzoj1951: [Sdoi2010]古代猪文(Lucas+CRT+欧拉定理)

https://www.lydsy.com/JudgeOnline/problem.php?id=1951 先欧拉降幂 然后模数质因数分解 分别计算组合数的结果,中国剩余定理合并 #include<cmath> #include<cstdio> #include<iostream> using namespace std; const int mod=999911659; const int phi=mod-1; typedef long long LL; int p[

bzoj1951 [Sdoi2010]古代猪文 ——数论综合

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1951 题意就是要求 G^( ∑(k|n) C(n,k) ) % p,用费马小定理处理指数,卢卡斯定理处理大组合数,取模用中国剩余定理合并: 好想难写的感觉(其实也不难写?): 关于中国剩余定理,可以看这篇博客:https://www.cnblogs.com/MashiroSky/p/5918158.html 第一次写中国剩余定理合并模数,还有一点不解的地方,写在注释里. 代码如下: #in