Codeforces325-B(二分搜索)
分析:问题可以转化为下面的等式求解问题:
由于n在10^18范围内,所以k的范围是从0到63即可,这样就可以枚举k,二分m,然后所有符合条件的就是答案了。
注意这里数据范围的处理,不注意的话就会溢出的。
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> using namespace std; typedef long long LL; LL a[100005]; LL c; void Solve(LL n) { LL k; for(k=0;k<63;k++) { LL l=1,r=3*1e9; if(k>=30) r=1000000000000000000>>k; while(l<=r) { LL mid=(l+r)>>1; LL ans=(((LL)1<<k)-1)*mid*2+mid*(mid-1); if(ans>2*n) r=mid-1; else if(ans<2*n) l=mid+1; else { if(mid&1) a[c++]=mid*((LL)1<<k); break; } } } } int main() { LL n,i; while(cin>>n) { c=0; Solve(n); sort(a,a+c); if(c==0) puts("-1"); else { for(i=0;i<c;i++) cout<<a[i]<<endl; } } return 0; }