6304 Chiaki Sequence Revisited
阿新 • • 發佈:2019-02-05
題意:給出了個計算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這道題的大佬。