zoukankan      html  css  js  c++  java
  • poj 2773 Happy 2006

    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 11161   Accepted: 3893

    Description

    Two positive integers are said to be relatively prime to each other if the Great Common Divisor (GCD) is 1. For instance, 1, 3, 5, 7, 9...are all relatively prime to 2006.

    Now your job is easy: for the given integer m, find the K-th element which is relatively prime to m when these elements are sorted in ascending order.

    Input

    The input contains multiple test cases. For each test case, it contains two integers m (1 <= m <= 1000000), K (1 <= K <= 100000000).

    Output

    Output the K-th element in a single line.

    Sample Input

    2006 1
    2006 2
    2006 3
    

    Sample Output

    1
    3
    5
    

    Source


      想说一下这题的大意,就是找出与m互质的第k个数

      这明显是一道数论的题,开始没有想到什么好的方法就暴力,毫无疑问TLE(注:正确的暴力是不会超时的)

      后来找了几份题解看了看,找的了正确的做法,用容斥原理求出和它不互质的个数,拿n一减,个数就出来了,

    不过这仍然存在一个问题,上面的TLE又跳了出来,又因为这里1到n(1<=n<=m)中间,n的值越大,与m互质

    的数更多,很符合二分的特点

      下面问题就变成了给了你一个从小到大排列的数组,找到k最早出现的位置(想想为什么,因为当从k-1增加到

    第k个的时候,k一定与m互质,所以才会增加一个互质的数)

      接下来问题就变得十分简单了,附上秒过的代码(第一次提交手抽,把某个地方的limit打成m,导致速度110ms)

    Code:

     1 /**
     2  * poj.org
     3  * Problem#2773
     4  * Accepted
     5  * Time:0ms
     6  * Memory:172k
     7  */
     8 #include<iostream>
     9 #include<cstdio>
    10 #include<cmath>
    11 using namespace std;
    12 typedef bool boolean;
    13 typedef long long ll;
    14 int m;
    15 ll k;
    16 int factor[50]; 
    17 int _count;
    18 /***
    19  * 分解质因数 
    20  */
    21 void init(int n){
    22     _count = 0;
    23     int limit = (int) sqrt(n + 0.5);
    24     for(int i = 2;i <= limit;i++){            //不用考虑i是否为指数 
    25         if(n == 0)    break;
    26         if(n % i == 0){
    27             factor[_count++] = i;        //保存质因数 
    28             while(n % i == 0) n /= i;    //除干净 
    29         }
    30     }
    31     if(n > 1) factor[_count++] = n; 
    32 }
    33 ll getCount(ll n){
    34     if(m == 1) return n;
    35     if(n == 1) return 1;
    36     long long result = n;
    37     for(int i = 1;i < (1 << _count );i++){    //遍历所有情况 
    38         long long temp = i, a = 1, b = 0;     
    39         for(int j = 0;j < _count&&temp != 0;j++){
    40             if((temp & 1 )== 1){        //用1来表示取第i个质数,0表示不去 
    41                 a *= factor[j];            //分母的乘积 
    42                 b++;                    //统计个数 
    43             }
    44             temp >>= 1;
    45         }
    46         if((b&1)==1) result -= n/a;        //个数为奇数,根据容斥原理,应该减 
    47         else result += n/a;                //个数为偶数,应该加 
    48     }
    49     return result;
    50 }
    51 int main(){
    52     while(~scanf("%d%ld",&m,&k)){        //当没有收到数据的时候是EOF(-1)取反后是0(false) 
    53         if(m == 1){
    54             printf("%ld
    ",k);
    55             continue;
    56         }
    57         if(k == 1){
    58             printf("1
    ");                //特殊处理,加快速度 
    59             continue;
    60         }
    61         ll from = 1;
    62         ll end = 1LL<<55; 
    63         ll result;
    64         init(m);
    65         while(from <= end){                //二分查找 
    66             ll mid = (from + end) >> 1;     
    67             ll c = getCount(mid);        //计算个数 
    68             if(c > k)    end = mid - 1;     
    69             else if(c < k) from = mid + 1;
    70             else{                        //这里不可以break,二分找到的第一个不一定是答案 
    71                 result = mid;            //例如数列1 1 1 2 3查找1,第一次找到的1不一定是最左边的 
    72                 end = mid - 1; 
    73             }
    74         }
    75         printf("%ld
    ",result);
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    敏捷开发设计模式的五大原则(读敏捷软件开发:原则、模式与实践笔记记录一下)
    使用AOP和Semaphore对项目中具体的某一个接口进行限流
    java正则使用全记录!
    推荐一本书学习springcloud书籍的SpringCloud微服务全栈技术与案例解析
    使用springboot Admin 2.0.6版本 集成监控springcloud微服务应用
    推荐一本学习Groovy的书籍Groovy程序设计!
    Datagrip 快捷键和常用插件持续更新一集一些使用技巧
    Eclipse中项目不会自动编译问题的坑和注意点
    使用Groovy的mixin方法注入,和mixedIn属性实现过滤链
    vscode常用快捷键和插件(持续更新),以及一些常用设置的坑和技巧
  • 原文地址:https://www.cnblogs.com/yyf0309/p/5686132.html
Copyright © 2011-2022 走看看