Bzoj 3110
Bzoj 1833

Bzoj 1951

coc youyl posted @ 2015年6月27日 20:12 in bzoj , 839 阅读

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1951

题目分类:数论

题意:

球G^m(mod 999911659)

m=sigma i|n {C(n,i)}

题解:

G^m(mod 999911659)=G^(m mod 999911658)(mod 999911659)

枚举约数,快速求出C(n,i)(mod 999911659

999911658=2*3*4679*35617

可以使用中国肾盂定理求出线性同余方程组的解。

程序:

#include<cstdio>
using namespace std;
long long f[5][40000];
long long ni[5]={0,1,1,1353,-4363};
long long w[5]={0,2,3,4679,35617};
const long long mod=999911659;
inline long long exp(long long x,long long y,long long md)
{
	long long ans=1;
	while (y!=0)
	{
		if(y&1)
		{
			y--;
			ans=(ans*x)%md;
		}
		else
		{
			y/=2;
			x=x*x%md;
		}
	}return ans;
}
inline void init()
{
	for (int i=1;i<=4;i++)
	{
		f[i][0]=1;
		for (int j=1;j<=w[i];j++)
		{
			f[i][j]=(f[i][j-1]*(long long)j)%w[i];
		}
	}
}
inline long long C(long long x,long long y,long long idx)
{
	if(x<y)return 0;
	return f[idx][x]*exp((f[idx][x-y]*f[idx][y]),w[idx]-2,w[idx])%w[idx];
}
inline long long lucas(long long x,long long y,long long idx)
{
	if(y==0)return 1;
	return lucas(x/w[idx],y/w[idx],idx)*C(x%w[idx],y%w[idx],idx)%w[idx];
}
long long a[5];
inline long long CRT()
{
	long long ans=0,M=1;
	for (int i=1;i<=4;i++)M*=w[i];
	for (int i=1;i<=4;i++)
	{
	//	printf("%I64d %I64d ",ni[i],a[i]);
		ans+=(a[i]*(M/w[i])*ni[i])%M;
		ans%=M;
	}
	while (ans<=0)
	{
		ans+=M;
	}return ans;
}
int main()
{
	init();
	long long n,m;
	while (scanf("%lld %lld",&n,&m)!=EOF)
	{
		m%=mod;
		a[1]=a[2]=a[3]=a[4]=0;
		for (int i=1;i*i<=n;i++)
		{
			if(n%i==0)
			{
				for (int j=1;j<=4;j++)
				{
					a[j]+=lucas(n,i,j);a[j]%=w[j];
					if(i*i!=n)a[j]+=lucas(n,n/i,j),a[j]%=w[j];
				}
			}
		//	printf("%d %I64d %I64d %I64d %I64d\n",i,a[1],a[2],a[3],a[4]);
		}printf("%lld\n",exp(m,CRT(),mod));
	}
	return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter