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

    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 
    

    Solution

    显然满足单调性,可以二分。

    然后问题转化为了(1)(n)内有多少个满足条件的数。

    对于一个满足条件的数,即每个质因子的指数都是1。

    对于一个数(x=prod_{i=1}^kp_i^{a_i}cdot s),其中前面的(prod)表示(forall i,a_igeqslant 2)的部分,后面是剩下的。

    考虑当且仅当(k=0)时,这个数才会被计一次,(k e 0)时,一次都不会记。

    可以想到这样一个函数:

    [sum_{d|n}mu(d)=[n=1] ]

    于是可以枚举每个完全平方数(x^2),剩下的质因子随便填,然后乘上(mu(x)),这样正好可以满足每个满足条件的数被记一次。

    #include<bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    
    #define ONLINE_JUDGE
    
    #ifdef ONLINE_JUDGE
    #define getchar() ((p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin)),p1==p2)?EOF:*p1++)
    #endif
    
    namespace fast_IO {
    	char buf[1<<21],*p1=buf,*p2=buf;
    
    	template <typename T> inline void read(T &x) {
    		x=0;T f=1;char ch=getchar();
    		for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    		for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    	}
    	template <typename T,typename... Args> inline void read(T& x,Args& ...args) {
    		read(x),read(args...);
    	}
    
    	char buf2[1<<21],a[80];int p,p3=-1;
    
    	inline void flush() {fwrite(buf2,1,p3+1,stdout),p3=-1;}
    	template <typename T> inline void write(T x) {
    		if(p3>(1<<20)) flush();
    		if(x<0) buf2[++p3]='-',x=-x;
    		do {a[++p]=x%10+48;} while(x/=10);
    		do {buf2[++p3]=a[p];} while(--p);
    		buf2[++p3]='
    ';
    	}
    	template <typename T,typename... Args> inline void write(T x,Args ...args) {
    		write(x),write(args...);
    	}
    }
    
    using fast_IO :: read;
    using fast_IO :: write;
    using fast_IO :: flush;
    
    const int maxn = 1e6+10;
    
    int pri[maxn],tot,vis[maxn],mu[maxn];
    
    void sieve() {
    	mu[1]=1;
    	for(int i=2;i<maxn;i++) {
    		if(!vis[i]) pri[++tot]=i,mu[i]=-1;
    		for(int j=1;j<=tot&&i*pri[j]<maxn;j++) {
    			vis[i*pri[j]]=1;
    			if(i%pri[j]==0) break;
    			mu[i*pri[j]]=-mu[i];
    		}
    	}
    }
    
    int check(int n) {
    	int tmp=0;
    	for(int i=1;i*i<=n;i++) tmp=tmp+mu[i]*n/(i*i);
    	return tmp;
    }
    
    void solve() {
    	int n,l,r,mid,ans=1;read(n);l=1,r=n*2;
    	while(l<=r) {
    		mid=((l+r)>>1);
    		if(check(mid)>=n) ans=mid,r=mid-1;
    		else l=mid+1;
    	}write(ans);
    }
    
    signed main() {
    	sieve();
    	int t;read(t);while(t--) solve();
    	flush();
    	return 0;
    }
    
  • 相关阅读:
    html学习之——标签语义化
    前端学习之---性能优化
    git学习之---如何把一个写好的项目传到GitHub上
    css学习体会之——块级元素,行内元素长宽设置
    部署ingress-nginx
    K8S
    ELK-Trie树
    ELK 日常问题处理
    GFS 日常操作
    MegaCli修复RAID5
  • 原文地址:https://www.cnblogs.com/hbyer/p/10208600.html
Copyright © 2011-2022 走看看