码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1951: [Sdoi2010]古代猪文

时间:2016-02-05 22:12:08      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

集各比较重要的数论定理于一身的题

如果没学过快速幂、费马小定理、lucas定理、中国剩余定理的,请关掉电脑学文化课去,OI不适合你,请出门左转自行百度/google

学完了这题就是大傻逼题了

另外注意特判n=P-1时,费马小定理不成立,直接输出0

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define ll long long

using namespace std;
const int P0=999911659; 
const int P1=999911658;
const int p[4]={35617,4679,3,2};

int pow(int x,int y,int P){
	int ret=1;
	while (y){
		if (y&1) ret=(ll)ret*x%P;
		x=(ll)x*x%P;
		y=y>>1;
	}
	return ret;
}

int inv(int x,int P){return pow(x,P-2,P);}

int fact[66666];
int C(int n,int m,int P){
	if (n<m) return 0;
	return (ll)fact[n]*inv(fact[n-m],P)%P*inv(fact[m],P)%P;
}
int lucas(int n,int m,int P){
	if (!n&&!m) return 1;
	return (ll)lucas(n/P,m/P,P)*C(n%P,m%P,P)%P;
}

int n,G;
int main(){
	scanf("%d%d",&n,&G);
	if (G==P0){puts("0");return 0;}
	for (int i=fact[0]=1;i<=p[0];++i) fact[i]=(ll)fact[i-1]*i%P1;
	int tot=0;
	for (int k=0;k<4;++k){
		int now=0;
		for (int i=1;i*i<=n;++i)if (n%i==0){
			(now+=lucas(n,i,p[k]))%=p[k];
			if (n/i!=i)
				(now+=lucas(n,n/i,p[k]))%=p[k];
		}
		(tot+=(ll)now*(P1/p[k])%P1*inv(P1/p[k],p[k])%P1)%=P1;
	}
	printf("%d\n",pow(G,tot,P0));
	return 0;
}

  

bzoj1951: [Sdoi2010]古代猪文

标签:

原文地址:http://www.cnblogs.com/wangyurzee7/p/5183528.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!