题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5297
题意:给你一个所有正整数的序列,然后去掉满足x^(2~r)的所有数(x为所有正整数,r>=2题目给出),问你现在这个序列的第n个数是什么
解:首先想到写一个函数func(y),它可以计算出给定数字y是序列中第几个数,这样我们大概可以二分答案~(事实上会TLE,得用迭代法,当然迭代的话也是用这个函数)
那么如何实现func:
首先想去掉满足x^2的所有数,我们可以用pow(y, 1/2)计算出y以下有多少个满足x^2的数
然后去掉满足x^3的,注意到这里x^6的数被去除了两次,那么我们可以进行容斥,这样func就实现了
实现了func以后,开始二分,结果各种TLE,迭代就过了(具体看代码,感觉迭代的复杂度就是玄学~)
1 /* 2 * Problem: 3 * Author: SHJWUDP 4 * Created Time: 2015/8/3 星期一 14:44:48 5 * File Name: 233.cpp 6 * State: 7 * Memo: 8 */ 9 #include <iostream> 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 #include <cmath> 14 15 using namespace std; 16 17 long long n; 18 int r; 19 vector<int> tmpTable; 20 vector<int> table; 21 long long cal(long long x, long long power) { 22 return pow(double(x+0.5), 1.0/power)-1; 23 } 24 void init() { 25 table.clear(); 26 for(int i=0; i<(int)tmpTable.size() && -tmpTable[i]<=r; i++) { 27 int a=tmpTable[i]; 28 int tmp=table.size(); 29 for(int j=0; j<tmp; j++) { 30 int b=table[j]; 31 if(abs(a*b)<=63) table.push_back(a*b); 32 } 33 table.push_back(a); 34 } 35 } 36 long long func(long long x) { 37 if(x==1) return 0; 38 long long res=x; 39 for(int power : table) { 40 long long tmp=pow(double(x+0.5), 1.0/abs(power))-1; 41 if(power<0) res-=tmp; 42 else res+=tmp; 43 } 44 return res-1; 45 } 46 int main() { 47 #ifndef ONLINE_JUDGE 48 freopen("in", "r", stdin); 49 // freopen("out", "w", stdout); 50 #endif 51 vector<int> vis(63, 0); 52 for(int i=2; i<63; i++) { 53 if(vis[i]!=0) continue; 54 tmpTable.push_back(-i); 55 for(int j=i+i; j<63; j+=i) { 56 vis[j]=1; 57 } 58 } 59 int T; 60 scanf("%d", &T); 61 while(T--) { 62 scanf("%I64d%d", &n, &r); 63 init(); 64 long long ans=n, tmp=-1; 65 while(tmp!=n) { 66 tmp=func(ans); 67 ans+=n-tmp; 68 } 69 printf("%I64d\n", ans); 70 } 71 return 0; 72 }