hdu5525 Product 费马小定理
来源:互联网 发布:微信推广源码 编辑:程序博客网 时间:2024/05/20 09:07
Product
Accepts: 21
Submissions: 171
Time Limit: 6000/3000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
给n个数A1,A2....An,表示N=∏i=1niAi。求N所有约数之积。
输入描述
输入有多组数据.每组数据第一行包含一个整数n.(1≤n≤105)第二行n个整数A1,A2....An,保证不全为0.(0≤Ai≤105).数据保证 ∑n≤500000.
输出描述
对于每组数据输出一行为答案对109+7取模的值.
输入样例
40 1 1 051 2 3 4 5
输出样例
36473272463
把N化成N=∏i=1kpiai,其中p为互不相等的质数,则含px个数为j的约数有ax+1∏i=1k(ai+1)个,而j的取值范围是0到ax,从而得到px在所有约数中出现了2(1+ax)ax∗ax+1∏i=1k(ai+1)次。根据费马小定理ap−1≡1(modp),统计ax时可以对p-1取模,由于后面还要除2,所以先对2(p-1)取模。求ax+1∏i=1k(ai+1)部分时不能取逆元,可以分别对前缀和后缀计算积。计算出N包含的所有质因子出现次数后用快速幂统计一遍,复杂度O(NlogN).
#include<iostream>#include<cstdio>#include<bitset>#include<vector>#include<queue>#include<set>#include<map>#include<cstring>#include<cmath>#include<algorithm>#define ll long long#define ull unsigned long long#define debug puts("======");#define inf (1<<30)#define eps 1e-8using namespace std;const int maxn=100010;ll mod=1000000007;ll M=1000000006;int prime[maxn];bool vis[maxn];int cnt;void getPrime(){ int N=100000; int m=sqrt(N+0.5); memset(vis,0,sizeof(vis)); for(int i=2;i<=m;i++) { if(vis[i]==0) { for(int j=i*i;j<=N;j+=i) vis[j]=1; } } cnt=1; for(int i=2;i<=N;i++) { if(!vis[i]) prime[cnt++]=i; }}int n;ll num[maxn];int pos[maxn];ll lef[maxn];ll rig[maxn];ll cal(ll a){ if(a%2==0) return a/2%M*((a+1)%M)%M; else return (a+1)/2%M*(a%M)%M;}ll powMod(ll a,ll b){ if(b==0) return 1; ll ans=powMod(a,b/2); ans=ans*ans%mod; if(b&1) ans=ans*a%mod; return ans;}int main(){ getPrime(); for(int i=1;i<cnt;i++) pos[prime[i]]=i; int a; while(~scanf("%d",&n)) { memset(num,0,sizeof(num)); for(int i=1;i<=n;i++) { scanf("%d",&a); int u=i; for(int j=1;j<cnt;j++) { if((ll)prime[j]*prime[j]>u) break; while(u%prime[j]==0) { u/=prime[j]; num[j]+=a; num[j]%=(2*M); } } if(u>1) { num[pos[u]]+=a; num[pos[u]]%=(2*M); } } int m; for(int i=cnt-1;i>=1;i--) { if(num[i]>0) { m=i; break; } } lef[0]=rig[m+1]=1; for(int i=1;i<=m;i++) lef[i]=lef[i-1]*(num[i]+1)%M; for(int i=m;i>=0;i--) rig[i]=rig[i+1]*(num[i]+1)%M; ll ans=1; for(int i=1;i<=m;i++) { ll tot=cal(num[i]); tot=tot*lef[i-1]%M*rig[i+1]%M; ans=ans*powMod(prime[i],tot)%mod; } printf("%lld\n",ans); } return 0;}
0 0
- hdu5525 Product 费马小定理
- hdu5525
- BestCoder Round #61 (div.2)(hdu5522,hdu5523,hdu5524,hdu5525(数论:费马小定理))
- HDU 5525(Product-费马小定理)
- hdu 5525 Product (费马小定理优化的快速幂)
- HDU 5525:Product 欧拉定理
- HDU5525(乘法原理)
- 威尔逊定理,费马小定理,欧拉定理
- 费马小定理
- 费马小定理
- 费马小定理
- 费马小定理
- 费马小定理
- 费马小定理
- 费马小定理
- 费马小定理
- 费马小定理
- 费马小定理
- 同步与异步的区别
- LightOJ - 1407 Explosion(2-SAT)
- No.1 Nim Game 取物游戏
- Intel- 64 与 IA-32架构软件开发人员手册 中文版
- 【学习笔记0001】Go初学者需要关注的50个注意事项
- hdu5525 Product 费马小定理
- Shiro使用和源码分析---3
- 在Total Commander下使用SVN
- No.2 flip game 翻转游戏
- 在javaweb中添加过滤器
- hudu 1050 sort oj上的易错点 贪心算法
- turtlesim
- No.3 Add Digits (digital root)
- ZOJ 2971-G - Give Me the Number-模拟