CodeForces - 1228C(质因数分解+贡献法)
题意
https://vjudge.net/problem/CodeForces-1228C
首先先介绍一些涉及到的定义:
定义prime(x)表示x的质因子集合。举例来说,prime(140)={2,5,7},prime(169)={13}。
定义g(x,p)表示存在一个最大的k∈N∗,使得x可以被p^k整除,那么g(x, p) = p^k。举例来说:
- g(45, 3) = 9 (45可以被3^2 = 9整除但是不能被3^3=27整除)
- g(63, 7) = 7 (63可以被7^1 = 7整除但是不能被7^2=49整除)
定义f(x, y)表示所有g(y,p) (p∈prime(x))的乘积,举例来说:
- f(30, 70) = g(70,2)·g(70,3)·g(70, 5) = 2^1·3^0·5^1 = 10
- f(525,63) = g(63,3)·g(63,5)·g(63,7) = 3^2·5^0·7^1 = 63
现在给出两个整数x和n,请计算出f(x,1)⋅f(x,2)…f(x,n) mod (10^9+7)的值。
思路
先算一下x=10,n=10的情况
f(10,1)=1 f(10,2)=g(2,2)=2 f(10,3)=1 f(10,4)=g(4,2)=4 f(10,5)=g(5,5)=5
f(10,6)=g(6,2)=2 f(10,7)=1 f(10,8)=g(8,2)=8 f(10,9)=1 f(10,10)=g(10,5)=10
容易发现,对于10的素因子2、5,2在2、4、6、8、10都出现了一次,在4,8又出现了一次,在8又出现了一次。所以对于素因子i,它的贡献是x^(n/x) * x^(n/x/x) * x^(n/x/x/x) * ……
所以对x质因数分解(分解到根号x即可),然后对每个质因子算贡献。
代码
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=200005; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) ll qpow(ll a,ll b) { ll res=1; while(b) { if(b&1) res=res*a%mod; a=a*a%mod; b>>=1; } return res; } int main() { std::ios::sync_with_stdio(false); ll x,n; cin>>x>>n; ll xx=x,gx=sqrt(x); ll ans=1; for(ll i=2; i<=gx; i++) { int f=0; if(xx==1) break; while(xx%i==0&&xx!=1) { xx/=i; f=1; } if(f) { ll nn=n; while(nn) { nn/=i; ans=ans*qpow(i,nn)%mod; } } } if(xx>1) { ll nn=n,i=xx; while(nn) { nn/=i; ans=ans*qpow(i,nn)%mod; } } cout<<ans<<endl; return 0; }