题目
题目链接:https://ac.nowcoder.com/acm/contest/5669/B
思路
这道题其实就是求这个数分解因数最大能分解几次
当时过的时候怕T 做了许多预处理 想复杂度 没下过到暴力就能过QWQ
暴力算法:
#include<bits/stdc++.h>
#define ll long long
//#define int long long
using namespace std;
//const int INF = 0x3f3f3f3f;
const int mod =1e9+7;
int main(){
// ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
scanf("%d",&t);
while(t--){
int n;ll m;
scanf("%d %lld",&n,&m);
ll res=1;
for(int i=2;i*i<=n;i++){//如果是i<=sqrt(n) 就会超时 sqrt函数复杂度好像是logn的
while(n%i==0){
n/=i;
res=(res*m)%mod;
}
}
if(n!=1) res=res*m%mod;
printf("%lld\n",res);
}
return 0;
}
预处理求最质因数算法:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
ll a[1000010];
bool vis[1000010],v1[1000010];
const ll mod=1e9+7;
vector<int> v;
inline void read(int &x){
char t=getchar();
while(!isdigit(t)) t=getchar();
for(x=t^48,t=getchar();isdigit(t);t=getchar()) x=x*10+(t^48);
}
void p(int n){
memset(vis,0,sizeof vis);
for(int i=2;i<n;i++){
if(!vis[i]){
v.push_back(i);
v1[i]=1;
}
for(int j=0;j<v.size()&&i*v[j]<n;j++){
vis[i*v[j]]=1;
if(i%v[j]==0) break;
}
}
}
int solve( ll x ) // 返回x的因子个数
{
int ans = 0;
int cnt=v.size();
for ( int i=0;v[i]<=sqrt(x)&&i<cnt; i++ ) { // 优化2
while ( x%v[i]==0 ) {
x /= v[i];
ans++;
}
}
if ( x>1 ) ans+=1; // //如果x不能被整分,说明还有一个素数是它的约数,此时tot=1
return ans;
}
ll quick_pow(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(){
// ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
scanf("%d",&t);
p(1000000);
while(t--){
int n,c;
read(n);
read(c);
if(v1[n]==1) printf("%lld\n",c);
else{
// cout<<solve(n)<<endl;
printf("%lld\n",quick_pow(c,solve(n)));}
}
return 0;
}