Educational Codeforces Round 1 A. Tricky Sum

A. Tricky Sum

問題:

1からnの和を計算する.しかし,2のk乗の数字は引く.

解法:

(1+n)*n/2からnまでの2k乗の和を2回引く.

分類:

算数

コード:

#include <bits/stdc++.h>
using namespace std;
 
const double PI = acos(-1);
const double EPS = 1e-15;
using ll = long long;
using ull = unsigned long long;
const int inf = 2e9;
const ll INF = 2e18;
const ll MOD = 1e9+7;
const ll MOD1 = 998244353;
typedef pair<ll,ll> P;
 
#define rep(i,a,b) for (int i = (a); i < (b); i++)
#define rrep(i,a,b) for (int i = (a); i >= (b); i--)
#define REP(i,n) rep(i,0,n)
#define RREP(i,n) rrep(i,n,0)
#define sz(s) (s).size()
#define pb push_back
#define fi first
#define se second
//#define mp make_pair
 
ll a[1000010];
vector<ll> v;
 
int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
 
  int t;
  cin >> t;
  ll sum = 1;
  a[0] = 1;
  v.pb(1);
  for (ll i = 1; sum <= MOD; i++) {
    sum *= 2;
    a[i] = sum;
    a[i] += a[i-1];
    v.pb(sum);
  }
  v.pb(INF);
  while (t--) {
    ll n;
    cin >> n;
    ll ret = n * (n + 1) / 2;
    int pos = upper_bound(v.begin(),v.end(),n) - v.begin();
    cout << ret - 2 * a[pos - 1] << endl;
  }
 
  return 0;
}