HUD 4704 Sum 费马小定理和快速幂
2016-03-29 17:51
337 查看
给定s(k)为k的划分数
求划分数的个数
比如当n=4时候
s(1)=(4)…………………………1
s(2)=(2,2)(1,3)(3,1)………3
s(3)=(1,1,2)(1,2,1)(2,1,1)……3
s(4)=(1,1,1,1)……………………1
所以是1+3+3+1=8
多列几个会发现要求的是2^(n-1)
然后1<=n<10^100000太大了会爆
这时候有个定理叫 费马小定理
费马小定理(Fermat Theory)是数论中的一个重要定理,其内容为: 假如p是质数,且(a,p)=1,那么
a(p-1)≡1(mod p)。即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。
在这里a=2,p=mod=1e9+7 刚好是一个质数
费马小定理怎么使用呢?
n=m+p
a^(n-1)%p=a^(m+p-1)%p
=(a^m*a^(p-1))%p
=(a^m%p)*(a^(p-1)%p)
=a^m%p
所以发现对于n来说mod-1是它的一个循环节我们可以对大数n取余处理然后在快速幂就好了
ACcode:
#include <map> #include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <stdlib.h> #include <iostream> #include <algorithm> const int mod=1e9+7; using namespace std; long long fpow(long long b){ long long a=2; long long ans=1; while(b){ if(b&1)///判断奇偶性if(b%2==1) ans=(ans*a)%mod; a=(a*a)%mod; b=b>>1; } return ans; } int main(){ char s[1000000]; while(~scanf("%s",s)){ long long n=0; int len=strlen(s); for(int i=0;i<len;++i) n=(n*10+(s[i]-'0'))%(mod-1);///mod-1为循环节 // cout<<num<<'\12'; if(n==0)n=mod-1; printf("%I64d\n",fpow(n-1)); } return 0; }
相关文章推荐
- VPC学习笔记
- Hadoop Rack Aware 机架感知
- SDWebImage实现原理
- 矢量量化神经网络,自组织竞争神经网络,自组织映射网络
- Asp.Net Repeater的两层嵌套以及遍历取值的简单实现(checkbox)
- React.js实现原生js拖拽效果及思考
- 考试
- URL的参数中出现中文用这个方法转换在拼接
- border opacity
- Masonry的使用
- linux系统基础及简单安装步骤
- UTF-8 的tomcat接受GBK请求乱码
- 基于AFNetworking3.0网络封装
- Java创建excel表格并下载
- Redhat hadoop2.7.2 eclipse配置
- spring mvc DispatcherServlet详解之前传---FrameworkServlet
- 学习资源网址
- 翻转子串
- 关于未来
- 自动交互式脚本--expect简介