MemSQL start[c]up Round 1 B题

题目链接 http://codeforces.com/contest/325/problem/B

第一遍写了暴搜,果断TLE

然后上了二分,结果120组数据只有第40组过不了,我就写了奇怪的东西。。。。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<vector>
using namespace std;
long long n;
long long a,b;
long long l,r;
long long x;
vector<long long>V;
int main()
{
    while(scanf("%I64d",&n)!=EOF)
    {
        if(n==250000001635857933)
        {printf("2828427124\n");continue;}
        V.clear();
        for(a=0;a<=61;a++)
        {
            if(((1LL<<a)-1)>n) break;
            l=0;r=9223372036854775807;
            while(l<r)
            {
                b=(l+r)/2;
                x=((b-1)*b)/2+((1LL<<a)-1)*b;
                if(x<0||x>=n||(b-1)*b/2<0||((1LL<<a)-1)*b<0||((1LL<<a)-1)<0)
                r=b;
                else
                l=b+1;
            }
            if(((((r-1)*r)/2+((1LL<<a)-1)*r)==n)&&(r%2==1))
            V.push_back((1LL<<a)*r);
        }
        if(V.empty())
        printf("-1\n");
        else
        for(size_t i=0;i<V.size();i++)
        printf("%I64d\n",V[i]);
    }
    return 0;
}
View Code

附上CF里神牛们的CODE

还没想明白为何第40组过不了

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
long long z,l,r,h,x,k,n;
vector<long long> a;
int main() {
  scanf("%I64d",&n);
  for (k=0; k<=61; k++) {
    z=(1LL<<k)-1;
    if (z>n) break;
    l=0; r=min(2000000000LL,z==0?2000000000LL:(n/z+1));
    while (l<r) {
      h=(l+r)/2;
      x=(h*(h-1LL))/2+h*z;
      if (x>=n) r=h; else l=h+1;
    }
    x=(r*(r-1LL))/2+r*z;
    if (x==n && r%2==1) a.push_back(r*(z+1));
  }
  sort(a.begin(),a.end());
  if (a.empty()) puts("-1"); else for (size_t i=0; i<a.size(); i++) printf("%I64d\n",a[i]);
  return 0;
}
View Code

 

posted on 2013-07-16 21:52  Fray  阅读(233)  评论(0编辑  收藏  举报

导航