# [HDU6304][数学] Chiaki Sequence Revisited

## 题目描述

$a_n=\begin{cases}1 & n = 1,2 \\ a_{n - a_{n-1}} + a_{n-1 - a_{n-2}} & n \ge 3\end{cases}$

## 题目分析

### 不可描述的做法

http://oeis.org/A046699

$a[1..] = {1,2,2,3,4,4,4,5,6,6,7,8,8,8,8,9,....}$

### 大概正确的规律

$\begin{cases} {f(2k+1) =1 }\\\\f(2k)=f(k)+1\end{cases}$

\begin {align} &g(n) = \sum_{k=1}^{n}f(k) \\ &g(n) = \sum^{\lfloor \frac{n-1}{2}\rfloor}_{k=0}f(2k+1) + \sum^{\lfloor \frac{n}{2}\rfloor}_{k=1}f(2k)\\ &g(n) = \Big\lceil\frac{n}{2}\Big\rceil + \sum^{ \lfloor \frac{n}{2}\rfloor}_{k=1} \{f(k)+1\}\\ &g(n) = \Big\lceil\frac{n}{2}\Big\rceil + \Big\lfloor\frac{n}{2}\Big\rfloor + g(\Big\lfloor\frac{n}{2}\Big\rfloor) \\ &g(n) = g(\Big\lfloor\frac{n}{2}\Big\rfloor)+n \\ \end {align}

$\begin{matrix} 1, 3, 5, 7, 9, \cdots ,2(t-1)+1 &\quad\quad\text{分别出现一次} \\ 2,6,10,14,18, \cdots ,4(t-1)+2 &\quad\quad\text{分别出现两次} \\ 4,12,20,28,36,\cdots,8(t-1)+4 &\quad\quad\text{分别出现三次} \\ \vdots &\vdots\\ \cdots 2^k(t-1)+2^{k-1} &\quad\quad\text{分别出现k次} \end{matrix}$

### 代码Code

/*
[HDU6304][数学]
Chiaki Sequence Revisited
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MOD = 1e9+7;
const int inv2 = 500000004;
int T;
LL n;
LL calc(LL n) {
if(n<=1) return n;
else return calc(n/2)+n;
}
void solve() {
LL l=n/2-30,r=n/2+30,m,p=-1;
//需要预先估计上下界减少二分次数,否则会TLE.
while(l<=r) {
m = (l+r)/2;
if(calc(m)>n) r=m-1;
else l=m+1,p=m;
}
LL rest = ((n - calc(p))%MOD+MOD)%MOD;
LL ans = 0, s, t, e, k, c=1, x, y;
for(LL i=1;; i<<=1,c++) {
if(i>p) break;
x = i%MOD;
y = 2*i%MOD;
s = x;
k = ((p-i)/(2*i)+1)%MOD;
e = (y*(k-1)%MOD+i)%MOD;
ans = (ans+c*(s+e)%MOD*k%MOD*inv2%MOD)%MOD;
}
ans = (ans + rest*((p+1)%MOD)%MOD)%MOD;
printf("%lld\n",ans+1);
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%lld",&n);
n--; //偏移一项
solve();
}
return 0;
}
posted @ 2018-07-24 17:29 UnderSilence 阅读(...) 评论(...) 编辑 收藏