题目链接:http://lightoj.com/volume_showproblem.php?problem=1032
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <algorithm> #include <queue> #include <vector> using namespace std; const int maxn = 33; const int INF = 0x3f3f3f; long long dp[maxn]; int sum[9] = {0,0,0,1,1,1,2,4,4}; long long int N; inline long long res(int i){ return (1<<i) + (1<<(i-1)); } int main() { freopen("E:\acm\input.txt","r",stdin); dp[2] = 1; for(int i=3;i<=31;i++){ dp[i] = 2*dp[i-1] + (1<<(i-2)); } int T; cin>>T; for(int cas=1;cas<=T;cas++){ cin>>N; printf("Case %d: ",cas); if(N <= 8){ printf("%d ",sum[N]); continue; } long long ans = 0; for(int i=30;i>=3;i--){ long long temp = 1<<i; if(N >= temp){ ans += dp[i]; long long diff = N - res(i); if(diff >= 0){ //这个地方没有加等号WA了两次。 ans += diff + 1; } N -= temp; } if(N == 0) break; } cout<<ans+sum[N]<<endl; } }