B. Math

time limit per test:1 second
memory limit per test:256 megabytes

Description:

JATC's math teacher always gives the class some interesting math problems so that they don't get bored. Today the problem is as follows. Given an integer n, you can perform the following operations zero or more times:

  • mul x: multiplies n by x (where x is an arbitrary positive integer).
  • sqrt: replaces nn with n−−√n (to apply this operation, n−−√n must be an integer).

You can perform these operations as many times as you like. What is the minimum value of n, that can be achieved and what is the minimum number of operations, to achieve that minimum value?

Apparently, no one in the class knows the answer to this problem, maybe you can help them?

Input:

The only line of the input contains a single integer nn (1≤n≤10^6,1≤n≤10^6) — the initial number.

Output:

Print two integers: the minimum integer n that can be achieved using the described operations and the minimum number of operations required.

Sample Input:

20

Sample Output:

10 2

题意:

对n可以进行开方以及乘以一个数这两种操作(无限次),求经过操作后最小的为多少。

题解:

唯一分解定理告诉我们,n可以分解成若干个质数的乘积,比如n=a1^p1*a2^p2*...*an^pn,其中a1,a2,.....,an为质数。

由于可以乘以一个任意的数,所以我们是可以改变p1,p2..pn的值的。我们假定现在已经把指数变为可多次开方的形式,那么最小的n值就是a1*a2*...*an。

现在主要问题是解决操作次数,我们设一个数t,t为2^t>=max(p1,p2,....,pn)的最小值,那么现在我们就可以进行t次开方。

最后再判断一下乘法操作就可以了。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std; typedef long long LL ;
const int N = 1e6+;
int tot,n;
int u[N],prim[N],vis[N],a[N]; int main(){
scanf("%d",&n);
for(int i=;i<=sqrt(n);i++){
for(int j=i*i;j<=n;j+=i){
if(!vis[j]) vis[j]=;
}
}
for(int i=;i<=n;i++) if(!vis[i]) prim[++tot]=i;
int tmp = n,cnt=;
while(tmp>){
if(tmp%prim[cnt]==){
tmp/=prim[cnt];
a[prim[cnt]]++;
}else{
cnt++;
}
}
int maxn = ;
cnt=;
LL ans = ,f = ;
bool flag=false;
for(int i=;i<=n;i++) if(a[i]){
maxn=max(maxn,a[i]),ans*=i;
}
for(int i=;i<=n;i++){
if(a[i]&&a[i]!=maxn) flag=true ;
}
while(){
if(f>=maxn){
if(flag) break ;
if(f==maxn) flag=false;else flag=true;
break;
}
f*=;
cnt++;
}
printf("%lld %d",ans,cnt+(flag==true));
return ;
}

后来我看了一下其它人的代码,十分简洁,发现不用把素数给筛出来,具体代码可以看下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std; int n,cnt,ans=;
vector <int > vec ; int main(){
scanf("%d",&n);
int maxn = ;
for(int i=;i<=n;i++){
cnt = ;
if(n%i==) ans*=i;
while(n%i==){
n/=i;
cnt++;
}
while(<<(maxn)<cnt) maxn++;
if(cnt) vec.push_back(cnt);
}
int flag = ;
for(int i=;i<vec.size();i++){
if(vec[i]!=(<<maxn)) flag=;
}
printf("%d %d",ans,flag+maxn);
return ;
}

Codeforces Round #520 (Div. 2) B. Math的更多相关文章

  1. Codeforces Round #520 (Div. 2) B. Math 唯一分解定理+贪心

    题意:给出一个x 可以做两种操作  ①sqrt(x)  注意必须是完全平方数  ② x*=k  (k为任意数)  问能达到的最小的x是多少 思路: 由题意以及 操作  应该联想到唯一分解定理   经过 ...

  2. Codeforces Round #520 (Div. 2) B math(素数因子的应用)

    题意: 给出一个n ; 有两个操作: 1,mul A   ,   n=n*A   : 2,sqrt()  ,  n=sqrt(n)  开更出来必须是整数 : 求出经过这些操作后得出的最小  n , 和 ...

  3. Codeforces Round #520 (Div. 2)

    Codeforces Round #520 (Div. 2) https://codeforces.com/contest/1062 A #include<bits/stdc++.h> u ...

  4. CF每日一练 Codeforces Round #520 (Div. 2)

    比赛过程总结:过程中有事就玩手机了,后面打的状态不是很好,A题理解错题意,表明了内心不在状态,B题想法和思路都是完全正确的,但是并没有写出来,因为自己代码能力不强,思路不是特别清晰,把代码后面写乱了, ...

  5. Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)

    https://codeforces.com/contest/1062/problem/E 题意 给一颗树n,然后q个询问,询问编号l~r的点,假设可以删除一个点,使得他们的最近公共祖先深度最大.每次 ...

  6. Codeforces Round #520 (Div. 2) Solution

    A. A Prank Solved. 题意: 给出一串数字,每个数字的范围是$[1, 1000]$,并且这个序列是递增的,求最多擦除掉多少个数字,使得别人一看就知道缺的数字是什么. 思路: 显然,如果 ...

  7. Codeforces Round #520 (Div. 2) D. Fun with Integers

    D. Fun with Integers 题目链接:https://codeforc.es/contest/1062/problem/D 题意: 给定一个n,对于任意2<=|a|,|b|< ...

  8. Codeforces Round #520 (Div. 2) C. Banh-mi

    C. Banh-mi time limit per test:1 second memory limit per test:256 megabytes 题目链接:https://codeforc.es ...

  9. Codeforces Round #520 (Div. 2) A. A Prank

    A. A Prank time limit per test   1 second memory limit per test    256 megabytes 题目链接:https://codefo ...

随机推荐

  1. 某CTF收集的Mysql爆表、爆字段语句

    Mysql特性 获取数据库名未知函数可爆数据库名 FUNCTION youcanneverfindme17.a does not exist 获取表名and linestring(pro_id)    ...

  2. 640. Solve the Equation

    class Solution { public: string solveEquation(string equation) { int idx = equation.find('='); , v1 ...

  3. linux文件IO操作篇 (二) 缓冲文件

    2. 缓冲文件操作 //规模较大 实时性低的文件 //当数据长度快要超过缓冲区的范围时,或者时间周期达到时,数据才被送往指定位置 //需要使用FILE * 作为文件标识符 //stdin 标准输入 / ...

  4. DESCRIBEFIELD

    実行時データ型識別.略語は RTTI です.プログラム実行時にデータ型を識別して処理を行う仕組みです.. DESCRIBE FIELD命令を使用 DESCRIBE FIELD命令を使用して.変数のデー ...

  5. python2.7练习小例子(十)

        10):古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?     程序分析:兔子的规律为数列1,1 ...

  6. 20145202马超《网络对抗》Exp4 恶意代码分析

    20145202马超<网络对抗>Exp4 恶意代码分析 1.实验后回答问题 (1)总结一下监控一个系统通常需要监控什么.用什么来监控. 虽然这次试验的软件很好用,我承认,但是他拖慢了电脑的 ...

  7. 【转】手把手教你:Ubuntu14+apache2+django1.7+python2.7下网页/网站部署

    本人亲自尝试了网上众多的部署网页/网站方法,绝大多数都未能试验成功,这次的项目光部署这块遇到了很多问题,大概耗费了我一个星期. 本着:王道论坛中的赠人玫瑰,手留余香的精神.我把自己一路所走的历程发布出 ...

  8. 将List中的数据更新到数据库中

    List中有相应的数据,更新到数据库如下: 1.根据关键字查找后删除: foreach (var item in objSelList) { ADDaAn da = db.ADDaAns.Find(i ...

  9. 常用模块(chardet)

    作用:检测二进制的编码格式,不是百分百正确 import chardet f = open('test.txt', 'rb')data = f.read()print(data)result = ch ...

  10. CodeForces - 948C(前缀和 + 二分)

    链接:CodeForces - 948C 题意:N天,每天生产一堆雪体积 V[i] ,每天每堆雪融化 T[i],问每天融化了多少雪. 题解:对 T 求前缀和,求每一堆雪能熬过多少天,再记录一下多余的就 ...