题意:
该题目有多组数据,每组数据给出一个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; }