首页 > 其他 > 详细

Codeforces Round #713 (Div. 3)-G - Short Task(质因子分解)

时间:2021-04-11 21:36:09      阅读:42      评论:0      收藏:0      [点我收藏+]

题目大意:

让我们用d(n)表示数字n的所有约数之和,即d(n)=∑k|nk。

例如,d (1) = 1, d (4) = 1 + 2 + 4 = 7, d(6) = 1 + 2 + 3 + 6 = 12。

对于一个给定数字c,找出使d(n)=c的最小n。

思路:

我们考虑nlogn的预处理,然后每次询问O(1)

也就是需要一个logn的分解质因子的方法

我们在用欧拉筛素数的时候,顺便处理出每个数的最小质因子

然后我们质因子分解的时候,我们每个数除她的最小质因子求幂

这样最坏情况下logn的(逃)

然后分解完质因子考虑如何求所有因子的和

技术分享图片

 

用这个公式就好了,等比数列求和然后相乘

 

 

技术分享图片
ll qpow(ll a, ll b) {
    ll ans = 1;
    while(b) {
        //    if(b & 1) ans = ans * a % mod;
        if(b & 1) ans = ans * a ;
        //    a = a * a % mod;
        a = a * a ;
        b >>= 1;
    }
    return ans;
}
int  x,p[10000002],vis[10000002],mi[10000002];
void oula() {
    for(int i=2 ; i<=10000001; i++) {
        if(vis[i]==0) p[++x] = i,mi[i]=i;
        for(int j=1 ; j<=x&&p[j]*i<10000002; j++) {
            vis[i*p[j]]=1;
            mi[i*p[j]] = p[j];
            if(i%p[j]==0) break;
        }
    }
}
 
ll cal(ll x) {
    ll temp=1;
 
    while(x>1) {
        ll  t = mi[x];
        ll sum=0;
        while(x%t==0) x/=t,sum++;
        temp*=(qpow(t,sum+1)-1)/(t-1);
        if(temp>10000000) return 10000001;
    }
    return temp;
}
int  c,a[10000002];
int main() {
    oula();
    for(int i=1 ; i<=10000000 ; i++) {
        ll num = cal(i);
        if(num<=10000000) {
            if(a[num]==0) a[num] = i;
            else continue;
        }
    }
    int _ ;
    _ = read();
    while(_--) {
        c=read();
        if(a[c]) out(a[c]);
        else out(-1);
        puts("");
    }
    return  0 ;
}
View Code

 

1933ms(逃)

听说隔壁数论爷用狄利克雷前缀和400+就过了

Codeforces Round #713 (Div. 3)-G - Short Task(质因子分解)

原文:https://www.cnblogs.com/UpMing/p/14644575.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!