【分析】枚举下数列,可以发现求的Ai其实就是i二进制表示中有几个1,那么sum{A1~Am}就是求整数1~m中的每个数的二进制加起来有几个1,这个可以用数位DP即可。
【AC CODE】0ms
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,n) for(int i = a; i < n; i++)
#define repe(i,a,n) for(int i = a; i <= n; i++)
#define per(i,n,a) for(int i = n; i >= a; i--)
#define clc(a,b) memset(a,b,sizeof(a))
const int INF = 0x3f3f3f3f, MAXN = 55;
LL dp[MAXN][MAXN];//dp[i][j]长度为i前面几位有j个1时包含1的总数
int bit[MAXN];
LL dfs(int len, int num, bool ismax)
{
if(!len) return num;
LL &ans = dp[len][num];
if(!ismax && ~ans) return ans;
int mx = ismax?bit[len]:1;
LL cnt = 0;
repe(i,0,mx)
{
if(i) cnt += dfs(len-1,num+1,ismax&&i == mx);
else cnt += dfs(len-1,num,ismax&&i==mx);
}
return ismax?cnt:ans = cnt;
}
int main()
{
#ifdef SHY
freopen("d:\\1.txt", "r", stdin);
#endif
clc(dp,-1);
int t;
scanf("%d", &t);
while(t--)
{
LL n;
scanf("%lld", &n);
int cnt = 0;
while(n)
{
bit[++cnt] = n&1;
n >>= 1;
}
printf("%lld\n", dfs(cnt,0,1));
}
return 0;
}