题目:http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=612
题意:给一个正整数n,n小于10^8,对于X^X达到n位时,求最小的X,注意是达到n。
分析:先求出第一个满足X^X的位数大于等于n位的X,然后从上到下枚举X,如果X^X的位数小于n时就break。那么i+1就是答案。
题目:http://codeforces.com/contest/325/problem/B
题意:给一个正整数n<=10^18,m是奇数,求的解有多少个,并按从小到大的顺序输出所有的。
分析:方法就是枚举k,二分m。
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> using namespace std; typedef long long LL; const int N = 1005; const LL INF = 1e18; const LL R = 3*1e9; LL S[N]; int cnt; void Binary_Search(LL n) { for(int k=0;k<63;k++) { LL l = 1; LL r = R; if(k >= 30) r = INF >> k; while(l <= r) { LL m = (l + r) >> 1; LL ans = (((LL)1 << k) - 1) * m * 2 + m * (m - 1); if(ans > 2*n) r = m - 1; else if(ans < 2*n) l = m + 1; else { if(m&1) S[cnt++] = m * ((LL)1 << k); break; } } } } int main() { LL n; cin>>n; cnt = 0; Binary_Search(n); sort(S,S+cnt); if(cnt == 0) puts("-1"); else { for(int i=0;i<cnt;i++) cout<<S[i]<<endl; } return 0; }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4282
题意:对于方程X^Z + Y^Z + XYZ = K,已知K求此方程解的个数,其中要求X<Y,Z>1,而K的范围是0到2^31。
分析:这道题明显的二分搜索题。
首先我们来分析Z的范围:由于X,Y为正整数,X < Y,则1 < X < Y, =====> Y >= 2
=> X^Z + Y^Z + XYZ > Y^Z
=> 2^Z <= Y^Z < 2^31
所以得到2 <= Z<31
对于Z=2时我们来特殊处理。所以只分析Z在3<=Z<31的情况。
我们再来分析X的范围:
对于方程X^Z + Y^Z + XYZ = K, X < Y,则有X^Z + Y^Z + XYZ > 2*X^Z + X*X*Z >= 2*X^3 + 3*X^2
即我们得到:2*X^3 + 3*X^2 < 2^31 解这个方程有:X < 1024
于是现在我们得到了3 <= Z < 31,1 <= X < 1024,当然Z=2特殊处理。接下来就直接枚举X,Z,来二分Y。
#include <iostream> #include <string.h> #include <stdio.h> #include <math.h> using namespace std; typedef long long LL; LL f[1300][32]; void Init() { for(int i=1; i<1300; i++) { f[i][0] = 1; for(int j=1; j<31; j++) { f[i][j] = f[i][j-1] * i; if(f[i][j] > 2147483648LL) break; } } } bool Binary_Search(int x,int z,int K) { int mid; int l=x+1; int r=1290; while(l <= r) { mid = (l + r) >> 1; if(f[mid][z] == 0) { r = mid - 1; continue; } LL ret = f[x][z] + f[mid][z] + x * mid * z; if(ret < K) l = mid + 1; else if(ret > K) r = mid - 1; else return true; } return false; } int main() { Init(); int K; while(~scanf("%d",&K),K) { LL ans = 0; int tmp = (int)sqrt(1.0*K); if(tmp*tmp == K) { if(tmp % 2) ans += tmp / 2; else ans += (tmp / 2 - 1); } for(int x=1; x<1024; x++) { for(int z=3; z<31; z++) { if(f[x][z] == 0) break; if(Binary_Search(x,z,K)) ans++; } } printf("%I64d\n",ans); } return 0; }