zoukankan      html  css  js  c++  java
  • BZOJ2440 [中山市选2011]完全平方数

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

    Description

    小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而这丝毫不影响他对其他数的热爱。
    这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了小X。小X很开心地收下了。
    然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?

    Input

    包含多组测试数据。文件第一行有一个整数 T,表示测试数据的组数。
    第2 至第T+1 行每行有一个整数Ki,描述一组数据,含义如题目中所描述。 

    Output

    含T 行,分别对每组数据作出回答。第 i 行输出相应的第Ki 个不是完全平方数的正整数倍的数。

    Sample Input

    4
    1
    13
    100
    1234567

    Sample Output

    1
    19
    163
    2030745

    HINT

    对于 100%的数据有 1 ≤ Ki ≤ 10^9, T ≤ 50

    正解:二分答案+容斥+莫比乌斯反演

    解题报告:

      最近刷莫比乌斯反演刷上瘾了...

      这类题都成套路了,预处理莫比乌斯函数,就是一个板子,然后扫一遍计算答案。

      这题要求第k个没有平方因子的数,直接二分答案,然后判断区间内的数的数量是否可行。其实这道题问的很裸啊,没有平方因子不就意味着μ(i)!=0吗...所以我们二分出了一个n之后,就计算区间的答案,根据容斥原理,满足要求的ans=n-只有一个质数因子次数大于等于2的个数+只有2个质数因子大于等于2的个数-...,这样的复杂度是sqrt(n)的。所以非常简单啦。

     1 //It is made by ljh2000
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #define N 100000
    14 using namespace std;
    15 typedef long long LL;
    16 const LL inf = (1LL<<31)-1;
    17 const int MAXN = 100011;
    18 LL l,r;
    19 int ans;
    20 int mobius[MAXN],k;
    21 int prime[MAXN],cnt;
    22 bool ok[MAXN];
    23 
    24 inline int getint()
    25 {
    26     int w=0,q=0; char c=getchar();
    27     while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 
    28     while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;
    29 }
    30 
    31 inline void init(){
    32     mobius[1]=1;
    33     for(int i=2;i<=N;i++) {
    34     if(!ok[i]) prime[++cnt]=i,mobius[i]=-1;
    35     for(int j=1;j<=cnt && prime[j]*i<=N;j++) {
    36         ok[i*prime[j]]=1;
    37         if(i%prime[j]) mobius[i*prime[j]]=-mobius[i];
    38         else { mobius[i*prime[j]]=0; break; }
    39     }
    40     }
    41 }
    42 
    43 inline bool check(LL x){
    44     LL div=sqrt(x); int tot=0;
    45     for(int i=1;i<=div;i++) {
    46     tot+=mobius[i] * (x/(i*i));
    47     }
    48     //tot=x-tot;
    49     if(tot>=k) return true;
    50     return false;
    51 }
    52 
    53 inline void work(){
    54     init(); int T=getint(); LL mid;
    55     while(T--) {
    56     k=getint(); l=1; r=inf; ans=inf;
    57     while(l<=r) {
    58         mid=(l+r)/2;
    59         if(check(mid)) ans=mid,r=mid-1;
    60         else l=mid+1;
    61     }
    62     printf("%d
    ",ans);
    63     }
    64 }
    65 
    66 int main()
    67 {
    68     work();
    69     return 0;
    70 }
  • 相关阅读:
    SGU 271 Book Pile (双端队列)
    POJ 3110 Jenny's First Exam (贪心)
    HDU 4310 Hero (贪心)
    ZOJ 2132 The Most Frequent Number (贪心)
    POJ 3388 Japanese Puzzle (二分)
    UVaLive 4628 Jack's socks (贪心)
    POJ 2433 Landscaping (贪心)
    CodeForces 946D Timetable (DP)
    Android Studio教程从入门到精通
    Android Tips – 填坑手册
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5958585.html
Copyright © 2011-2022 走看看