hdu 5525(数学题)

思路很简单啊,为了好计算,考虑每个素因子出现的次数,然后很容易想到递推方法。

这个题目:

1 , pow_mod(a , b , mod) 当mod是素数时且b远大于mod 那么 pow_mod(a, b,mod ) = pow_mod(a , b%(mod-1),mod);

2 , 求1 ->x 的和不能直接x*(x+1)/2 % mod ; 因为有除法啊。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N = 1e5 + 100;
const ll lim = 1e18 + 10;

#define rep1(i,x,y) for(int i=x;i<=(int)y;i++)
#define rep(i,n) for(int i=0;i<(int)n;i++)

const ll mod = 1e9 + 7;
const ll mod2 = 1e9 + 6;
ll pow_mod(int a,ll b){
   ll ans = 1 , te = a;
   while(b > 0){
       if(b & 1) ans=ans*te%mod;
       b>>=1;
       te=te*te%mod;
   }
   return ans;
}
bool vis[N]={0};
vector<int> pri;
int n,a[N],K,po[N];
void init(){
    int m = (sqrt(N));
    for(int i=2;i<=m;i++) if(!vis[i])
       for(int j=i*i;j<N;j+=i) vis[j]=1;
    for(int i=2;i<N;i++) if(!vis[i]) {
          pri.push_back(i);
          po[i] = pri.size()-1;
    }
    K = pri.size();
}
ll cnt[N];
void get(int i,int x){
    int m=sqrt(x + 0.5);
    for(auto v : pri){
        if(v > m || x == 1) break;
        while(x % v ==0){
            x/=v; cnt[po[v]]+=i;
        }
    }
    if(x > 1) cnt[po[x]]+=i;
}
int mul(ll x) {
    ll a = x;
    ll b = x + 1;
    if(a & 1) b /= 2;
    else a /= 2;
    a %= mod2;
    b %= mod2;
    return a * b % mod2;
}
ll le[N],ri[N];
int main()
{
   init();
   while(scanf("%d",&n)==1){
      rep(i,K) cnt[i] = 0;
      rep1(i,1,n){
         scanf("%d",&a[i]); get(a[i],i);
      }
      ll ans = 1;
      le[0] = ri[K-1] = 1;
      rep1(i,1,K-1) le[i] = le[i-1]*(cnt[i-1]+1)%mod2;
      for(int i=K-2;i>=0;i--) ri[i] = ri[i+1]*(cnt[i+1]+1)%mod2;
      rep(i,K){
        ll ji = pow_mod(pri[i],(ll)(le[i]*ri[i]%mod2)*mul(cnt[i])%mod2);
        ans = ans*ji%mod;
      }
      cout<<ans<<endl;
   }
   return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值