BZOJ 1951 lucas定理 中国剩余定理
来源:互联网 发布:java执行sql语句 编辑:程序博客网 时间:2024/06/16 22:35
传送门
照旧记录一下,不然担心以后碰到类似的题依旧不知道怎么做……
题意:求G^(sigma(C(N,i)))%MOD,MOD=999911659,i是N的因子(包括1和本身)
思路:首先幂次非常大,所以先降幂次,即sigma(C(N,i))%(MOD-1)+(MOD-1),那么关键就是求sigma(C(N,i))%(MOD-1),我们可以遍历能整除N的数,但999911658是一个合数,它可以分解为四个素数的乘积,即999911658=2*3*4679*35617,那么就可以分别求x1=sigma(C(N,i))%2、x2=sigma(C(N,i))%3、x3=sigma(C(N,i))%4679、x4=sigma(C(N,i))%35617,若x=sigma(C(N,i))%999911658,那么x%x1=2、x%x2=3、x%x3=4679、x%x4=35617,那么就可以用中国剩余定理求得x了。可以发现素数都比较小,所以可以阶乘预处理。这个题还有个需要注意的地方,就是G=999911659的时候结果就是0了,可是我测试了几组数据,发现不写这个,最后结果也都是0,不知道哪组数据不是0了……
完整代码:
#include <iostream>#include <string.h>#include <stdio.h>using namespace std;typedef long long LL;LL mod[4]={2,3,4679,35617};const int MOD=999911659;LL fac[4][40000];LL a[4];LL quick_mod(LL a,LL b,LL p){ LL ans=1; a%=p; while(b) { if(b&1) { ans=ans*a%p; b--; } b>>=1; a=a*a%p; } return ans;}void init(){ for(int i=0;i<4;i++) fac[i][0]=1; for(int i=0;i<4;i++) for(int j=1;j<mod[i];j++) fac[i][j]=fac[i][j-1]*j%mod[i];}LL C(LL n,LL m,LL p,int cnt){ if(m>n) return 0; LL ans=fac[cnt][n]*quick_mod(fac[cnt][m]*fac[cnt][n-m],p-2,p)%p; return ans;}LL Lucas(LL n, LL m,LL p,int cnt){ if(m==0) return 1; return C(n%p,m%p,p,cnt)*Lucas(n/p,m/p,p,cnt);}LL gcd(LL a,LL b){ if(b==0) return a; else gcd(b,a%b);}void exgcd(LL a,LL b,LL &x,LL &y){ if(b==0) { x=1; y=0; return ; } LL x1,y1; exgcd(b,a%b,x1,y1); x=y1; y=x1-(a/b)*y1;}LL CRT(LL a[]){ LL M = 1; LL ans = 0; for(LL i=0; i<4; i++) M *= mod[i]; for(LL i=0; i<4; i++) { LL x, y; LL Mi=M/mod[i]; exgcd(Mi,mod[i],x,y); ans=(ans+Mi*x*a[i])%M; } if(ans<0) ans += M; return (ans+M)%M;}int main(){ init(); LL N,G; while(scanf("%lld%lld",&N,&G)!=-1) { for(int i=0;i<4;i++) a[i]=0; if(G==MOD) { printf("0\n"); continue; } for(int i=1;i*i<=N;i++) { if(N%i==0) { LL x=i; a[0]=(a[0]+Lucas(N,x,mod[0],0))%mod[0]; a[1]=(a[1]+Lucas(N,x,mod[1],1))%mod[1]; a[2]=(a[2]+Lucas(N,x,mod[2],2))%mod[2]; a[3]=(a[3]+Lucas(N,x,mod[3],3))%mod[3]; x=N/i; if(N!=i*i) { a[0]=(a[0]+Lucas(N,x,mod[0],0))%mod[0]; a[1]=(a[1]+Lucas(N,x,mod[1],1))%mod[1]; a[2]=(a[2]+Lucas(N,x,mod[2],2))%mod[2]; a[3]=(a[3]+Lucas(N,x,mod[3],3))%mod[3]; } } } LL temp=CRT(a)+MOD-1; LL ans=quick_mod(G,temp,MOD)%MOD; cout<<ans<<endl; } return 0;}
阅读全文
0 0
- BZOJ 1951 lucas定理 中国剩余定理
- bzoj 1951(Lucas定理+中国剩余定理)
- BZOJ 1951 古代猪文 (Lucas 中国剩余定理)
- BZOJ 1951: [Sdoi2010]古代猪文(Lucas定理 &&中国剩余定理&&费马小定理)
- BZOJ-1951-古代猪文-SDOI2010-费马小定理+欧拉函数+lucas定理+中国剩余定理
- [BZOJ 1951] 古代猪文【Lucas定理/费马小定理/中国剩余定理/扩展欧几里得】
- bzoj 1951: [Sdoi2010]古代猪文 费马小定理+中国剩余定理+lucas定理+快速幂
- BZOJ 1951 费马小定理 + Lucas定理 + 乘法逆元 + 中国剩余定理 + 快速幂
- [BZOJ 1951][Sdoi2010]古代猪文:Lucas定理|中国剩余定理|费马小定理|扩展欧几里得
- bzoj 1951: [Sdoi2010]古代猪文 (Lucas定理+中国剩余定理)
- hdu5446 lucas+中国剩余定理
- 【总结】lucas 定理 + 中国剩余定理
- HDU 5446 lucas定理 + 中国剩余定理
- hdu4373 lucas定理+中国剩余定理
- BZOJ-1951 古代猪文 (组合数取模Lucas+中国剩余定理+拓展欧几里得+快速幂)
- 【BZOJ 1951】 [Sdoi2010]古代猪文|数论|中国剩余定理|Lucas
- BZOJ 1951 浅谈猪王国古代文字及中国剩余定理合并半拓展LuCas
- HDU5446 Unknown Treasure Lucas+中国剩余定理
- 狄利克雷卷积与积性函数
- 贪心,递归,动态规划,及分治算法之间的区别和联系(二)
- spark之5:配置文件
- 练习 2-5 编写函数 any(s1, s2),将字符串s2中的任一字符在字符串s1中第一次出现的位置作为结果返回。如果s1中不包含s2中的字符,则返回-1。
- ubuntu16 jdk7 install&config
- BZOJ 1951 lucas定理 中国剩余定理
- A Knight's Journey
- 继承和多态
- GAWK 学习:AWK 语言基础
- 使用回调函数实现一个简单的计算器;
- Java8中内置的四大核心函数式接口
- [挖坑][uoj]多项式乘法 FFT
- JZOJ2017.08.05 C组
- 【凸包 Graham法 极角排序】poj 2007 Scrambled Polygon