1. 程式人生 > >6304 Chiaki Sequence Revisited

6304 Chiaki Sequence Revisited

題目連結

題意:給出了個計算a[i]的公式,然後讓你求a[1~n]的和。

分析:好的,我們簡單粗暴的先打個表,發現規律(個屁),每一個a[i]出現的次數是lowbit(a[i])長度次,比如16出現的次數是lowbit(16) = 10000,長度為5次(我也不知道這是什麼神奇的東西),接下來就可以寫程式碼了,每一部分可以等差數列求和搞,一些細節會在下面的程式碼裡面註釋。
這裡寫圖片描述

更正:二分check那裡,應該是x=a[i],算出對應的i。

(參考了vj上一位不認識大佬“zstu_LLY”的程式碼,不然可能都這題都補不了)

#include <bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a)) #define ALL(x) x.begin(),x.end() #define pii pair<int,int> #define eps 1e-4 inline long long lowbit(long long x){return x&-x;} const int N = 1e6+10; const long long mod = (long long)1e9+7; const int INF=0x3f3f3f3f; const long long LINF=(1LL<<62); typedef
long long LL; typedef unsigned long long ULL; //#define LOCAL const double PI = acos(-1.0); using namespace std; LL n,inv2,p[63]; LL q_pow(LL base, LL b){ LL res = 1; while(b){ if(b&1) res = res*base%mod; base = base*base%mod; b>>=1; } return res; } bool check(LL x){ //為什麼要這麼寫呢,看上面打的表,除以每個2^i就可以得出2^i有多少個,這樣子加完就得到對應的a[x]是多少。
LL temp = 0; for(int i = 0; i <= 62; i++){ temp += x/p[i]; if(temp >= n-1) return true; } return temp >= n-1; } LL cal(LL x){ LL temp = 0; for(int i = 0; i <= 62; i++) temp += x/p[i]; return temp; } int main(){ #ifdef LOCAL freopen("out.txt", "w", stdout); #endif // LOCAL inv2 = q_pow(2,mod-2); //2的逆元,等下等差數列求和的時候要用 p[0] = 1; for(int i = 1; i <= 62; i++) p[i] = p[i-1]*2; //預處理2^i int T; scanf("%d",&T); while(T--){ scanf("%lld",&n); if(n==1){ printf("1\n"); continue; } LL l = max(1LL,n/2-30), r = min(n,n/2+30), mid, pos; while(l<=r){ mid = (l+r)>>1; if(check(mid)){ //二分找n對應的a[n]; pos = mid; //pos即為a[n] r = mid-1; }else l = mid+1; } LL res = pos-1, now = 0; //這裡pos-1是因為在a[n]位置的n可能不是剛好符合2^i,所以要找前面一個,前面一個必定是符合2^i個的。 for(int i = 0; i <= 62; i++){ if(p[i]>res) break; LL temp = res/p[i]; temp %= mod; now = (now+p[i]%mod*(temp+1)%mod*temp%mod*inv2%mod)%mod; //等差數列求和,不要忘記Mod } now = (now+(n-1-cal(res)%mod)%mod*pos%mod)%mod; //剩下這裡就是那些不完整的a[n]了 printf("%lld\n",(1+now)%mod); } return 0; }

ps:dls說這場多校,4+銅,6+銀,7+金的樣子,所以儘量補到6題吧,而這道題通過的人又蜜汁的多orz,就不得不補了。在看過一份又一份天書一樣的程式碼之後終於看到一份比較友好的,讓補題成為可能。再次感謝vj上shared這道題的大佬。