题目链接

Problem Description
Chiaki is interested in an infinite sequence $$$a_1,a_2,a_3,...,$$$ which is defined as follows:
$$$a_n=
\begin{cases}
1, & \text{$$$n=1,2$$$} \\
a_{n-a_{n-1}}+a_{n-1-a_{n-2}} & \text{$$$n\ge 3$$$}
\end{cases}$$$
Chiaki would like to know the sum of the first $$$n$$$ terms of the sequence, i.e. $$$\sum_{i=1}^{n}a_i$$$. As this number may be very large, Chiaki is only interested in its remainder modulo $$$(10^9+7)$$$.
Input
There are multiple test cases. The first line of input contains an integer $$$T$$$ $$$(1≤T≤10^5)$$$, indicating the number of test cases. For each test case:
The first line contains an integer $$$n$$$ $$$(1≤n≤10^{18})$$$.
Output
For each test case, output an integer denoting the answer.
Sample Input
10
1
2
3
4
5
6
7
8
9
10
Sample Output
1
2
4
6
9
13
17
21
26
32

学习了这篇大佬的博客

题意
求数列的前n项和
思路

打表+分析找规律:

规律1:数量和的规律

首先观察$$$A$$$,前几项为1, 2, 2, 3, 4, 4, 4, 5, 6, 6, ...,发现数列$$$A$$$其实是1,2,3,4,5,...依次出现,只是个数在发生变化。

定义$$$c_n$$$为$$$n$$$在$$$A$$$中出现的次数,前几项为1, 2, 1, 3, 1, 2, 1, 4, ...,发现奇数项$$$c_{2k+1}=1$$$,偶数项$$$c_{2k}=c_k+1$$$。

定义$$$s_n$$$为$$$c_n$$$的前$$$n$$$项和,则有如下规律:

$$$s_{2*k}$$$=$$$(c_1+c_3+...+c_{2k-1})+(c_2+c_4+...+c_{2*k})$$$=$$$n+(c_1+c_2+...+c_k)+n$$$=$$$2n+s_k$$$,

$$$s_{2*k+1}$$$=$$$(c_1+c_3+...+c_{2*k+1}+(c_2+c_4+...+c_{2*k}))$$$=$$$n+1+(c_1+c_2+c_k)+n$$$=$$$2n+1+s_k$$$

综上可得$$$s_n$$$=$$$s_{\lfloor \frac{n}{2}\rfloor}+n$$$

$$$s_n$$$的含义是,1~n在A中总共出现了多少次

规律2:单个n出现次数的规律

观察$$$c_n$$$发现,

1,    3,    5, ..., 1+2*k 出现1次

2,    6,  10, ..., 2+4*k 出现2次

4,  12,  20 ,..., 4+8*k 出现3次

n的出现次数符合这样的规律:从$$$2^t$$$开始,公差为$$$2^{t+1}$$$的数列中的每个数在A中出现$$$t+1$$$次。

结论1中,我们知道了1~n在A中总共出现了多少次,那么在结论2中,我们还可以对它们求和:把1~n重新组合为若干个等差数列,每个等差数列的首项一定是$$$2^t$$$,而尾项则是不超过n的最大$$$2^t+2^{t+1}*k$$$;通过遍历$$$2^t$$$不大于n的所有$$$t$$$,可以快速的求出所有1~n的和。

有了这些准备,求A当前n项和就可以这样:由于前n项并不一定包含了全部的1~$$$a_n$$$,只能直接求全部的1~$$$a_{n}-1$$$的和,再求有几个的$$$a_n$$$。

但是$$$a_n$$$是未知的,为了求$$$a_n$$$,可以利用规律1,二分查找一个x,使得$$$s_{x-1}<n<s_x$$$,那么也就意味着,A的第$$$s_{x-1}+1$$$~$$$s_{x}$$$项都是x,那么$$$a_n$$$就是x;另一方面,A的前n项中,$$$a_n$$$的数量就是n-$$$s_{x-1}$$$。

注意

打表+分析发现,$$$n$$$和$$$s_n$$$大约为1:2的关系,也就是说在二分寻找$$$x$$$的时候,大约有2(x-1)<n<2x的关系,也就是说,搜索的范围缩小到了n/2的附近。具体长度大概估计就可以了。

代码
#include<stdio.h>
/*
* HDU6304 Chiaki Sequence Revisited 数学题学习
* an为原数列从第二项开始,前几项为:1,2,2,3,4,4,4,5,6,6,...
*
* PART 1
* n的数量和的规律
* 记cn为n在{ai}中出现次数,前几项为:1,2,1,3,1,2,1,4,...
* 打表+分析发现,c(2*k+1)=1, c(2*k)=c(k)+1
* 设sn为cn前n项和
* s(2*n)=n项奇数项+n项偶数项=c(1)+c(3)+...+c(2*n-1)+c(2)+c(4)+...+c(2*n)=n+c(1)+...c(n)+n=s(n)+2*n
* 同理,s(2*n+1)=(n+1)项奇数项+n项偶数项=n+1+s(n)+n=s(n)+2*n+1
* 综上,s(n)=s(n/2)+n;
* 于是可以在log(N)内求出s(n)
* s(n)的含义为1~n在{ai}中总共有多少个,也就是在{ai}中,最后一个ai=n的编号i=s(n)
* 为了求出第i个ai,可以通过二分查找,找到s(j)<i<s(k),那么ai就是k
* 于是,可以用log(N)*log(N)求出第i个ai
*
*
* PART 2
* n出现次数的规律
* 打表+分析发现
* 1, 3, 5, ..., 1+2*k 出现1次
* 2, 6, 10, ..., 2+4*k 出现2次
* 4, 12, 20 ,..., 4+8*k 出现3次
* 规律:2^t的所有倍数出现t+1次
* 于是对于任何一个n,通过遍历t,利用等差数列和x出现次数的方法,在log(N)内求出小于n的所有ai的和
*
*
* PART 3
* {ai}前n项求和过程分为:
* log(N)*log(N)求出an
* log(N)求出小于an的所有ai的和
* log(N)求出最后一个ax=an-1的编号,那么所有an的和为an*(n-ax)
*
*/ typedef long long ll;
const ll mod = ; //log(N)求cn前n项和,也就是求不大于an的一共有几项
ll sum(ll n)
{
if (n <= )return n;
ll res = (sum(n >> ) + n);//注意这里不能取模
return res;
} //求sn大于等于key的最小an
ll bins(ll l, ll r,ll key)
{
ll mid;
while (l+<r)
{
mid = (l + r) >> ;
if (sum(mid) >= key)
r = mid;
else l = mid;
}
return r;
} int main()
{
int kase;
ll n;
scanf("%d", &kase);
while (kase--)
{
scanf("%lld", &n); n--;//我们考虑的an数列是从原数列的第二项开始的,相应的个数要-1
/*
* 打表+分析发现,i和sum(i)大约为1:2的关系
* 也就是说an和n的关系大约为1:2
* 缩小搜索区间到n/2附近
*/
ll an = bins((n>>)-, (n>>)+, n);
ll ans = ;//原数列的第一个1 for(ll wide=,base=,t=;base<an;base=wide,wide<<=,t++)
{
//等差数列求和:base,base+wide,...base+k*wide
//求k为小于an的最大情况
ll k = (an - base-) >> t;//除wide等价于右移t位
ll help = (k + )%mod;
ll temp = (((help*help)%mod)*(base%mod))%mod;
ans = (ans + ((t%mod)*temp)%mod) % mod;
}
//再加上前n个数里所有的an
ans = (ans + ((an%mod)*((n%mod +(mod- (sum(an - )%mod)))))%mod)%mod;
printf("%lld\n", ans);
}
}

2018 杭电多校1 - Chiaki Sequence Revisited的更多相关文章

  1. 2018 杭电多校2 - Naive Operations

    题目链接 Problem Description In a galaxy far, far away, there are two integer sequence a and b of length ...

  2. 2018 杭电多校1 - Distinct Values

    题目链接 Problem Description Chiaki has an array of n positive integers. You are told some facts about t ...

  3. hdu6312 2018杭电多校第二场 1004 D Game 博弈

    Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  4. 2018 杭电多校3 - M.Walking Plan

    题目链接 Problem Description There are $$$n$$$ intersections in Bytetown, connected with $$$m$$$ one way ...

  5. 2018杭电多校第二场1003(DFS,欧拉回路)

    #include<bits/stdc++.h>using namespace std;int n,m;int x,y;int num,cnt;int degree[100007],vis[ ...

  6. 2018杭电多校第六场1009(DFS,思维)

    #include<bits/stdc++.h>using namespace std;int a[100010];char s[20];int zhiren[100010];vector& ...

  7. 2018杭电多校第五场1002(暴力DFS【数位】,剪枝)

    //never use translation#include<bits/stdc++.h>using namespace std;int k;char a[20];//储存每个数的数值i ...

  8. 2018杭电多校第三场1003(状态压缩DP)

    #include<bits/stdc++.h>using namespace std;const int mod =1e9+7;int dp[1<<10];int cnt[1& ...

  9. 2019杭电多校一 L. Sequence (NTT)

    大意: 给定序列$a$, 给定$m$个操作, 求最后序列每一项的值. 一共$3$种操作, 其中第$k$种操作将序列变为$b_i=\sum\limits_{j=i-kx}a_j$, $(0\le x,1 ...

随机推荐

  1. javascript array.property.slice.call

    function foo() { //var var1=Array.prototype.slice.call(arguments); var var1=[].slice.call(arguments) ...

  2. JavaScript基础part2

    JavaScript对象 在JavaScript中除了null和undefined以外其他的数据类型都被定义成了对象,也可以用创建对象的方法定义变量,String.Math.Array.Date.Re ...

  3. Hibernate-关系映射

    1.为什么用Hibernate框架: java程序数据保存的变化: * 内存存在:java基础中, 数据保存在内存中,只在内存中暂时存在 * 文件保存:有io/流之后,数据可以保存到文件中 * 数据库 ...

  4. 全国Uber优步司机奖励政策 (1月4日-1月10日)

    本周已经公开奖励整的城市有:北 京.成 都.重 庆.上 海.深 圳.长 沙.佛 山.广 州.苏 州.杭 州.南 京.宁 波.青 岛.天 津.西 安.武 汉.厦 门,可按CTRL+F,搜城市名快速查找. ...

  5. 北京Uber优步司机奖励政策(1月4日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. 北京Uber优步司机奖励政策(9月28日~10月4日)

    用户组:优步北京人民优步A组(适用于9月28日-10月4日) 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不 ...

  7. 成都Uber优步司机奖励政策(1月17日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  8. 【LG2481】[SDOI2011]拦截导弹

    [LG2481][SDOI2011]拦截导弹 题面 洛谷 题解 可以看出第一问就是一个有关偏序的\(LIS\),很显然可以用\(CDQ\)优化 关键在于第二问 概率\(P_i=\) \(总LIS数\) ...

  9. spl_autoload_register()函数

    一.__autoload 这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数.看下面例子: printit.class.php <?php class PRINTI ...

  10. Hadoop3.0新特性

    1. Hadoop3.0简介 Hadoop 2.0是基于JDK 1.7开发的,而JDK 1.7在2015年4月已停止更新,这直接迫使Hadoop社区基于JDK1.8重新发布一个新的Hadoop版本,而 ...