[HDU-6304] Chiaki Sequence Revisited
阿新 • • 發佈:2019-02-06
求
There are multiple test cases. The first line of input contains an integer , indicating the number of test cases. For each test case:
The first line contains an integer .
思路
序列中某個值 出現的次數是
然後二分得到
然後可以 時間內求出
然後 減掉多加的部分就得到了答案
#pragma GCC optimize ("O2")
#include<bits/stdc++.h>
using namespace std;
const int MAXN = (int)1e5 + 5;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-8;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int MOD = 1000000007;
ll d[64];
ll f(ll n) {
ll num = 0;
for(ll i = 1; d[i] <= n; ++i) {
num += i * ((n / d[i] + 1 ) / 2);
}
return num + 1;
}
int sum(ll n) {
ll res = 0;
for(ll i = 1; d[i] <= n; ++i) {
//易錯
(res += i * ((d[i] % MOD + d[i] % MOD + (2 * d[i]) % MOD * (((n / d[i] + 1) / 2 - 1) % MOD) % MOD) % MOD * ((n / d[i] + 1) / 2 % MOD) % MOD * 500000004 % MOD) % MOD) %= MOD;
}
return (int)res;
}
ll work(ll n) {
// 一定要加速收斂
ll low = max(n / 2, 0LL), top = n / 2 + 30;
while(top - low > 1) {
ll mid = (low + top) >> 1;
if(f(mid) >= n) top = mid;
else low = mid;
}
return top;
}
void slove(ll n) {
ll sop = work(n);
ll pos = f(sop);
int ans = sum(sop) + 1;
ans -= (pos - n) * sop % MOD;
printf("%d\n", (ans + MOD) % MOD);
}
ll read(ll &x) {
char c;
while((c = getchar()) <= 32);
for(x = 0; c >= '0'; c = getchar()) x = x * 10 + c - '0';
}
int main()
{
d[1] = 1;
for(int i = 2; i < 64; ++i) d[i] = d[i - 1] << 1;
int T;ll n;
while(scanf("%d", &T) != EOF) {
while(T--) {
read(n);
slove(n);
}
}
return 0;
}