HDU5525(乘法原理)
来源:互联网 发布:linux 通配符 编辑:程序博客网 时间:2024/06/02 20:36
首先把每一个数拆成质因数的乘积,把对应的次数累计起来。然后设第i个质因数的指数累计的和是ai,那么i^t(0<=t<=ai)这个因子出现的次数就是(1+a1)*(1+a2)*...*(1+ak)/(1+ai)。
然后各种取模。
#include <cstdio>#include <algorithm>#include <cstring>#include <vector>#include <iostream>using namespace std;#define maxn 111111long long mod = 1e9+7;long long num[maxn], a[maxn];vector <int> fac[maxn];long long pre[maxn], last[maxn]; //前缀乘积,后缀乘积bool is_prime[maxn];long long prime[maxn], cnt;long long n;long long kk;long long qpow (long long a, long long b) { if (b == 0) return 1; long long ans = qpow (a, b/2); ans = ans*ans%mod; if (b&1) { ans = ans*a%mod; } return ans%mod;}long long get (long long cur, int pos, int tot) { long long ans = 1; long long mod2 = mod-1; if (num[cur]&1) { ans = (num[cur]+1)/2%mod2*(num[cur]%mod2)%mod2; } else ans = (num[cur]/2)%mod2*((num[cur]+1)%mod2) % mod2; if (tot == 1) { return ans; } else if (pos == 0) { ans = ans*last[1]%mod2; } else if (pos == tot-1) { ans = ans*pre[pos-1]%mod2; } else ans = ans*pre[pos-1]%mod2*last[pos+1]%mod2; return ans;}void solve () { long long ans = 1; unsigned long long gg = 1; int tot = 0; for (int i = 0; i < cnt && prime[i] <= n; i++, tot++) { } for (int i = 0; i < tot; i++) { pre[i] = (i == 0 ? (num[prime[i]]+1)%(mod-1) : (num[prime[i]]+1)%(mod-1)*pre[i-1]%(mod-1)); } for (int i = tot-1; i >= 0; i--) { last[i] = (i == tot-1 ? (num[prime[i]]+1)%(mod-1) : (num[prime[i]]+1)%(mod-1)*last[i+1]%(mod-1)); } for (int i = 0; i < tot; i++) { long long cur = prime[i]; ans *= qpow (cur, get (cur, i, tot)); ans %= mod; } printf ("%lld\n", ans);}int main () { //freopen ("in", "r", stdin); cnt = 0; memset (is_prime, 1, sizeof is_prime); for (int i = 2; i <= 100000; i++) { if (is_prime[i]) { prime[cnt++] = i; for (int j = i+i; j <= 100000; j += i) { is_prime[j] = 0; } } } for (int i = 1; i <= 100000; i++) { fac[i].clear (); } for (int i = 1; i <= 100000; i++) { for (int j = i; j <= 100000; j += i) { fac[j].push_back (i); } } while (scanf ("%lld", &n) == 1) { memset (num, 0, sizeof num); for (int i = 1; i <= n; i++) { scanf ("%lld", &a[i]); for (int j = 1; j < fac[i].size (); j++) { long long cur = fac[i][j]; long long tot = 0, m = i; while (m%cur == 0) { tot += a[i]; m /= cur; } num[cur] += tot; } } solve (); } return 0;}
0 0
- HDU5525(乘法原理)
- hdu5525
- 加法原理乘法原理
- hdu5525 Product 费马小定理
- pku 2346 乘法原理
- 乘法原理之应用
- 乘法计数原理
- CUDA:矩阵乘法原理
- 二进制乘法原理
- Lightoj1028 【数学-乘法原理】
- bzoj1123 求割点+乘法原理
- 加法原理与乘法原理
- 加法原理与乘法原理
- 加法原理和乘法原理
- POJ2346 Lucky tickets (乘法原理)
- 加法乘法原理、排列组合、线性规划
- 大数乘法的计算原理
- 【高科技数学原理】矩阵乘法
- HDU 5525 Product
- 单例模式的实现
- Android任务管理器的设计实现
- HDU 5523 Game
- Leap Motion 使用OpenCV获取和显示图像
- HDU5525(乘法原理)
- SDUT 2500 统计N!中包含末尾0 的个数
- HDU 5524 Subtrees
- python 文件读写查找、替换相关简单操作
- BestCoder Round #61 (div.2) HDU5523 Game
- git 服务器搭建 for linux
- HDU-5512 Pagodas(GCD)
- 数据结构实验一(1)
- Http Chunked Transfer Coding