您的位置:首页 > 其它

bzoj 1951: [Sdoi2010]古代猪文

2016-03-18 06:07 411 查看
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define ll long long
#define mul 999911659
using namespace std;
int n,g,a[4];
int sh[4]={2,3,4679,35617},C1[4][35618];
void exgcd(int a1,int a2,int &x,int &y)
{
if(!a2)
{
x=1;
y=0;
return;
}
exgcd(a2,a1%a2,x,y);
int t=x;
x=y;
y=t-a1/a2*y;
}
int kuai(ll n,int k,int p)
{
int ans=1;
for(;k;)
{
if(k%2)
ans=(ans*n)%p;
n=(n*n)%p;
k/=2;
}
return ans;
}
int C(int n,int m,int p)
{
if(n<m)
return 0;
return C1[p]
*kuai(C1[p][m]*C1[p][n-m],sh[p]-2,sh[p])%sh[p];
}
int lucas(int n,int m,int p)
{
if(!m)
return 1;
return (C(n%sh[p],m%sh[p],p)*lucas(n/sh[p],m/sh[p],p))%sh[p];
}
int solve()
{
int x,y,a1,b1,a2,b2;
a1=sh[0];
b1=a[0];
for(int i=1;i<4;i++)
{
a2=sh[i];
b2=a[i];
exgcd(a1,a2,x,y);
x=((b2-b1)*x%a2+a2)%a2;
b1=b1+x*a1;
a1=a1*a2;
}
return b1;
}
int main()
{
scanf("%d%d",&n,&g);
if(g==mul)
{
printf("0\n");
return 0;
}
for(int i=0;i<4;i++)
{
C1[i][0]=1;
for(int j=1;j<=sh[i];j++)
C1[i][j]=(C1[i][j-1]*j)%sh[i];
}
for(int i=1;i<=sqrt(n);i++)
if(n%i==0)
{
for(int j=0;j<4;j++)
{
a[j]=(a[j]+lucas(n,i,j))%sh[j];
if(i!=n/i)
a[j]=(a[j]+lucas(n,n/i,j))%sh[j];
}
}
printf("%d\n",kuai(g,solve(),mul));
return 0;
}


经典的数学题。。。。

题目就有点难懂,求G^M mod P M=∑ i|N C(N,i) P=999911659

用lucas定理,中国剩余定理合并模线性方程组。http://hzwer.com/4407.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: