zoukankan      html  css  js  c++  java
  • CF598A Tricky Sum

    题意:

    该题目有多组数据,每组数据给出一个n,让你求出从1到n的和,但是其中每当遇到一个数是2的次幂时,就要变加为减。例如输入n=4,那么计算算式为-1-2+3-4=-4,因为1是2^0,2是2^1,4是2^2。共有t组数据。

      其实做法很简单,把从1到n的和用等差数列算出来,然后用log2n计算出不大于n的2的幂次共有多少个,用等比数列求和公式求出它们的和,减去两倍的它即可。

    但是我发现WindowsXP居然卡精度严重,有很高的精度流失,

    kepa=log(n)/log(2);当n=8时在Linux和Windows7下跑出来kepa都是3,

    但WindowsXP跑出来居然是2,为了解决这个问题我们只能这样写kepa=(log(n)/log(2)+0.0000000001);

    总体代码如下:

    #include <algorithm>
    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <map>
    #include <string>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        register ll p(1),a(0);register char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
        if(ch=='-') p=-1,ch=getchar();
        while(ch>='0'&&ch<='9') a=a*10+ch-48,ch=getchar();
        return a*p;
    }
    ll t,n,kepa;
    inline ll fast(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            
            if(b&1) ans*=a;
            a*=a;
            b>>=1;
        }
        return ans;
    }
    int main()
    {
    //    freopen("input","r",stdin);
    //    freopen("output","w",stdout);
        t=read();
        while(t--)
        {
            n=read();
            kepa=(log(n)/log(2)+0.0000000001);
    //        printf("%d",kepa);
            printf("%I64d
    ",( (1ll+n)*n/2ll )-( (fast(2,kepa+1)-1ll)*2ll) );
        }
        return 0;
    }
  • 相关阅读:
    go if 判断 完成随机分数的评级
    go for循环
    go 常量2
    go 常量定义和使用
    更新数据库某字段数据为流水号
    BPM设定操作超时
    BPM打印按钮
    BPM链接处理
    项目管理
    公司规划
  • 原文地址:https://www.cnblogs.com/cold-cold/p/10023927.html
Copyright © 2011-2022 走看看