西安电子科技大学第16届程序设计竞赛G题

链接: https://www.nowcoder.com/acm/contest/107/G
来源:牛客网

题目描述

众所周知,汀老师是XDUACM实验室最优秀的人,无论是学习还是打游戏。今天他突然想到一个好玩的游戏。规则是这样的,在游戏中他要得到n个小国,初始的时候小国和小杰各有1个。经过了很久的修炼,汀老师学会了两种魔法,他每次可以动用自己的智慧来使用魔法。

第一个魔法:(小杰变小国)可以将自己的智慧复制和当前小杰一样数量的小国出来;

第二个魔法:(小国大爆发)可以将当前的小杰变成和小国的数量一样,然后小国的数量加倍!

因为汀老师的智力是无限多的,他不关心花掉的智力大小。但是好学的汀老师想尽快得到n个小国,使得能有更多的时间去读paper和打比赛。他想问问你,最少需要使用多少次魔法可以得到n个小国。

得到了n个小国后,汀老师去学习,但是小国们基因突变在电脑里越来越多!他们来组织汀老师学习,现在告诉汀老师我要得到更多的同伴!

输入描述:

多组数据,第一行一个正整数T(T<=100000)表示数据组数。
接下来T行,每行一个正整数n(n<=10^6)。

输出描述:

对于每组数据输出一个整数,表示得到n个小国汀老师最少需要使用多少次膜法。
示例1

输入

2
1
3

输出

0
2


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int vis[1000010];
long long Ans=0;
inline void dfs(int x,int now,int sum) {
    if(x==1) {
        Ans+=sum*(now-1);
        return;
    }
    if(vis[x]!=now) {
        Ans+=sum*(now-1);
        dfs(x/vis[x],vis[x],1);
    }
    else
        dfs(x/vis[x],now,sum+1);
}
int main() {
    memset(vis,0x3f,sizeof vis);
    vis[1]=1;
    for(int i=2;i<=1e6;++i)
        if(vis[i]==0x3f3f3f3f)
            for(int j=i;j<=1e6;j+=i)
                vis[j]=min(vis[j],i);
    int T,x;
    cin>>T;
    while(T--) {
        cin>>x;
        Ans=0;
        dfs(x,0,0);
        cout<<Ans<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40507857/article/details/80038020