LightOJ - 1050 (唯一分解+推公式+乘法逆元)

题意:求a^b的所有约数和对1e9+7取模的结果

思路:对于一个数p,进行唯一分解,则p=P1^M1*P2^M2*...*Pn^Mn,则p的所有约数之和等于(P1^0+P1^1+...+P1^M1)*(P2^0+P2^1+...+P2^M2)*...*(Pn^0+Pn^1+...+Pn^Mn),

p^t=P1^(M1*t)*P2^(M2*t)*...*Pn^(Mn*t),每一个(Pn^0+Pn^1+...+Pn^Mn)利用等比数列可以直接推出公式为(Pn^(Mn*t+1)-1)/(Pn-1),用快速幂和乘法逆元即可。

注意:n的唯一分解只需要试遍sqrt(n)的所有质数即可,若最后n除不尽,那么最后的n一定是质数。

  1 #include <iostream>
  2 #include <queue>
  3 #include <stack>
  4 #include <cstdio>
  5 #include <vector>
  6 #include <map>
  7 #include <set>
  8 #include <bitset>
  9 #include <algorithm>
 10 #include <cmath>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <string>
 14 #include <sstream>
 15 #include <time.h>
 16 #define x first
 17 #define y second
 18 #define pb push_back
 19 #define mp make_pair
 20 #define lson l,m,rt*2
 21 #define rson m+1,r,rt*2+1
 22 #define mt(A,B) memset(A,B,sizeof(A))
 23 using namespace std;
 24 typedef long long LL;
 25 const double PI = acos(-1);
 26 const int N=1e5+10;
 27 const LL mod=1e9+7;
 28 const int inf = 0x3f3f3f3f;
 29 const LL INF=0x3f3f3f3f3f3f3f3fLL;
 30 vector<LL> prime;
 31 int vis[N];
 32 void init()
 33 {
 34     mt(vis,0);
 35     LL m=sqrt(N+0.5);
 36     for(LL i=2;i<=m;i++)
 37     {
 38         if(!vis[i])for(LL j=i*i;j<=N;j+=i)vis[j]++;
 39     }
 40     for(LL i=2;i<N;i++)if(!vis[i])prime.pb(i);
 41 }
 42 void gcd(LL a,LL b,LL& d,LL& x,LL& y)
 43 {
 44     if(!b){d=a;x=1;y=0;}
 45     else{gcd(b,a%b,d,y,x);y-=x*(a/b);}
 46 }
 47 LL inv(LL a,LL n)
 48 {
 49     LL d,x,y;
 50     gcd(a,n,d,x,y);
 51     return d==1?(x+n)%n:-1;
 52 }
 53 LL pow_mod(LL a,LL n)
 54 {
 55     LL res=1;
 56     while(n)
 57     {
 58         if(n&1)res=(res*a)%mod;
 59         a=(a*a)%mod;
 60         n/=2;
 61     }
 62     return res;
 63 }
 64 LL solve(LL a,LL n)
 65 {
 66     LL ans,p;
 67     ans=(pow_mod(a,n)-1+mod)%mod;
 68     p=inv(a-1,mod);
 69     return (ans*p)%mod;
 70 }
 71 int main()
 72 {
 73 #ifdef Local
 74     freopen("data.txt","r",stdin);
 75 #endif
 76     ios::sync_with_stdio(false);
 77     cin.tie(0);
 78     init();
 79     int T;
 80     LL n,m,ans;
 81     cin>>T;
 82     for(int d=1;d<=T;d++)
 83     {
 84         cout<<"Case "<<d<<":"<<" ";
 85         ans=1;
 86         cin>>n>>m;
 87         for(int i=0;i<prime.size()&&n!=1;i++)
 88         {
 89             int k=0;
 90             if(n%prime[i]==0)
 91             {
 92                 while(n%prime[i]==0)
 93                 {
 94                     n/=prime[i];
 95                     k++;
 96                 }
 97                 ans=(ans*solve(prime[i],(LL)(k*m+1)))%mod;
 98                 k=0;
 99             }
100         }
101         if(n>1)ans=(ans*solve(n,(LL)(m+1)))%mod;
102         cout<<ans<<endl;
103     }
104 #ifdef Local
105     cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
106 #endif
107 }

时间: 2024-10-27 09:32:44

LightOJ - 1050 (唯一分解+推公式+乘法逆元)的相关文章

zoj 3903 Ant(推公式,逆元)

Ant Time Limit: 1 Second      Memory Limit: 32768 KB There is an ant named Alice. Alice likes going hiking very much. Today, she wants to climb a cuboid. The length of cuboid's longest edge is n, and the other edges are all positive integers. Alice's

hdu 3524 Perfect Squares 推公式求逆元

Perfect Squares Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 501    Accepted Submission(s): 272 Problem Description A number x is called a perfect square if there exists an integer b satisfy

CodeForces 300C Beautiful Numbers(乘法逆元/费马小定理+组合数公式+快速幂)

C. Beautiful Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Vitaly is a very weird man. He's got two favorite digits a and b. Vitaly calls a positive integer good, if the decimal

HDU 1576 (乘法逆元)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1576 题目大意:求(A/B)mod 9973.但是给出的A是mod形式n,n=A%9973. 解题思路: 两种思路,一种从乘法逆元角度,另一种从扩展GCD推公式角度. ①乘法逆元: 先来看下逆元和乘法逆元的关系,对于A*X=B,有X=A-1*B,A-1就是普通的逆元了,在这里就是倒数. 如果A*X=B mod n,变成同余式了,那么A-1依然是存在的,只不过不是倒数了,一般把同余之后的逆元称为乘法

【bzoj4517】[Sdoi2016]排列计数 组合数+乘法逆元+dp

题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是稳定的 满足条件的序列可能很多,序列数对 10^9+7 取模. 输入 第一行一个数 T,表示有 T 组数据. 接下来 T 行,每行两个整数 n.m. T=500000,n≤1000000,m≤1000000 输出 输出 T 行,每行一个数,表示求出的序列数 样例输入 5 1 0 1 1 5 2 100 50 10

(light oj 1102) Problem Makes Problem (组合数 + 乘法逆元)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1102 As I am fond of making easier problems, I discovered a problem. Actually, the problem is 'how can you make n by adding k non-negative integers?' I think a small example will make things clea

POJ 1845-Sumdiv 题解(数论,约数和公式,逆元,高中数学)

题目描述 给定A,B,求A^B的所有因数的和,再MOD 9901 输入 一行两个整数 A 和 B. 输出 一行,一个整数 样例输入 2 3 样例输出 15 提示 对于100%的数据满足:0 <= A,B <= 50000000 这道题首先要想到有一个因数和公式 f[a] = ( 1 + p1 + p1^2 + .... + p1^q1 ) * ( 1 + p2 + p2^2 + .... + p2^q2 ) * ...... * ( 1 + pn + pn^2 +.....+ pn^qn )

UVa 11174 (乘法逆元) Stand in a Line

题意: 有n个人排队,要求每个人不能排在自己父亲的前面(如果有的话),求所有的排队方案数模1e9+7的值. 分析: <训练指南>上分析得挺清楚的,把公式贴一下吧: 设f(i)为以i为根节点的子树的排列方法,s(i)表示以i为根的子树的节点总数. f(i) = f(c1)f(c2)...f(ck)×(s(i)-1)!/(s(c1)!s(c2)!...s(ck)!) 按照书上最开始举的例子,其实这个式子也不难理解,就是先给这些子树确定一下位置,即有重元素的全排列. 子树的位置确定好以后,然后再确定

乘法逆元...Orz

最近打的几场比赛,都出现了有关逆元的题目,今天就整理了一下... 求乘法逆元的几种方法:http://www.cnblogs.com/james47/p/3871782.html 博文转载链接:http://blog.csdn.net/acdreamers/article/details/8220787 今天我们来探讨逆元在ACM-ICPC竞赛中的应用,逆元是一个很重要的概念,必须学会使用它. 对于正整数和,如果有,那么把这个同余方程中的最小正整数解叫做模的逆元. 逆元一般用扩展欧几里得算法来求