http://acm.hdu.edu.cn/showproblem.php?pid=6304

题意

给出一个数列的定义,a[1]=a[2]=1,a[n]=a[n-a[n-1]]+a[n-1-a[n-2]](n>=3)。求前n项和,n<=1e18。

分析

一看就是得打表找规律或推公式的题目。

先把a[i]打出来: 1 1 2 2 3 4 4 4 5 6 6...

乍眼一看每个数字出现的次数有点意思,于是打出每个数出现次数:

数值   1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16

次数   2  2  1  3  1  2  1  4  1   2    1    3    1    2    1    5

感觉第一个1很不和谐啊,先忽略这个1看看:

数值   1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16

次数   1  2  1  3  1  2  1  4  1   2    1    3    1    2    1    5

可以看到前2^i个数的出现次数是由前2^(i-1)个数复制两次,并把2^i的次数+1得到的。

这样就得到数值出现次数的规律了,设cnt[i]为前2^i个数的次数之和,那么cnt[i]=2*cnt[i-1]+1。

有了cnt[i],对于一个下标n,可以求出a[n]的值,相反也可以求出值为a[n]的第一个位置。

然后怎么求前n项和呢?把相同出现次数的值输出看看:

1-- 1,3,5,7,9....

2-- 2,6,10,14...

3-- 4,12,20,28...

4-- 8,24,40,56...

....

很明显的规律,对于次数k,对应数值形成一个首项为2^(k-1),公差为2^k的等差数列。这个等差数列的每个值都出现k次。

所以,可以枚举次数,计算以a[n]为上界的项数,再把这个等差数列的和*次数加到答案中。

需要注意,计算等差数列时不能把a[n]算进去,因为a[n]出现的次数在n的限制下是不完全的,需要另外计算,这时就用到上面计算的a[n]出现的第一个位置了,由此算出a[n]实际出现的次数,再加到答案中。

由于数据是ll级别,出现相乘时不要忘记先模一下。

其它细节看代码。

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const ll mod = 1e9 + ; ll cnt[],p[];
//预处理2^i和cnt[i]
void init(){
cnt[]=p[]=;
for(int i=;i<=;i++) cnt[i]=*cnt[i-]+,p[i]=*p[i-];
}
//计算a[n]的数值
ll caln(ll n){
if(n==) return ;//特殊处理
n--;//由于规律从实际的第二个开始计算
ll an = ;
for(int i=;i>=;i--){
while(cnt[i]<=n){
n-=cnt[i];
an+=p[i];
}
}
return an;
}
//根据a[n]计算最早出现的位置
ll gps(ll an){
if(an==) return ;
an--; //同上
ll pos=;
for(int i=;i>=;i--){
while(p[i]<=an){
an-=p[i];
pos+=cnt[i];
}
}
return pos+;
}
int main() {
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
int T;
ll n;
scanf("%d",&T);
init();
ll _inv = ;//2的逆元
while(T--){
scanf("%lld",&n);
ll an = caln(n);
ll cnt = n - gps(an);//a[n]出现的实际次数
ll ans = ;
for(int i=;p[i-]<=an;i++){//枚举次数,终结条件为某个等差数列的首项大于a[n]
ll x1 = p[i-]; //首项
ll d = p[i]; //公差
//项数。注意,正常的项数应该是((an-x1)/d+1),但这里不能保证a[n]全部出现了,
//所以当((an-x1)%d==0)时说明a[n]位于当前的等差数列中,需要根据实际个数来计算,于是不+1
ll num = ((an-x1)%d==)?((an-x1)/d):((an-x1)/d+);
ll xn = x1 + (num-)*d; //尾项
ll sum = (x1%mod+xn%mod)%mod*(num%mod)%mod*_inv%mod; //等差数列前num项和
ans = (ans+i*sum%mod)%mod; //加入答案,共出现i次
if((an-x1)%d==)
ans=(ans+cnt*(an%mod)%mod)%mod; //a[n]位于此数列,特别计算一下。
}
printf("%lld\n",ans+);//由于计算中忽略了第一项1,最后加上
}
return ;
}

HDU - 6304(2018 Multi-University Training Contest 1) Chiaki Sequence Revisited(数学+思维)的更多相关文章

  1. 2018 杭电多校1 - Chiaki Sequence Revisited

    题目链接 Problem Description Chiaki is interested in an infinite sequence $$$a_1,a_2,a_3,...,$$$ which i ...

  2. hdu 4915 Parenthese sequence--2014 Multi-University Training Contest 5

    主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4915 Parenthese sequence Time Limit: 2000/1000 MS (Ja ...

  3. hdu 4902 Nice boat--2014 Multi-University Training Contest 4

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=4902 Nice boat Time Limit: 30000/15000 MS (Java/Othe ...

  4. hdu 4925 Apple Tree--2014 Multi-University Training Contest 6

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4925 Apple Tree Time Limit: 2000/1000 MS (Java/Others ...

  5. HDU校赛 | 2019 Multi-University Training Contest 6

    2019 Multi-University Training Contest 6 http://acm.hdu.edu.cn/contests/contest_show.php?cid=853 100 ...

  6. HDU校赛 | 2019 Multi-University Training Contest 5

    2019 Multi-University Training Contest 5 http://acm.hdu.edu.cn/contests/contest_show.php?cid=852 100 ...

  7. HDU校赛 | 2019 Multi-University Training Contest 4

    2019 Multi-University Training Contest 4 http://acm.hdu.edu.cn/contests/contest_show.php?cid=851 100 ...

  8. HDU校赛 | 2019 Multi-University Training Contest 3

    2019 Multi-University Training Contest 3 http://acm.hdu.edu.cn/contests/contest_show.php?cid=850 100 ...

  9. HDU校赛 | 2019 Multi-University Training Contest 2

    2019 Multi-University Training Contest 2 http://acm.hdu.edu.cn/contests/contest_show.php?cid=849 100 ...

随机推荐

  1. ram自己写?用IP?

    前言 ram这种东西,可以用ip方便,也可以自己写代码描述它. 以下讨论单口ram:8bit*256 流程 1.IP: 使用IP当然是最方便的事情啦,但可移植性差而且可定制性较差. 仿真波形: 2.V ...

  2. MT【249】离心率两题

    椭圆$\dfrac{x^2}{a^2}+\dfrac{y^2}{b^2}=1,(a>b>0)$的一个焦点为$F$,过$F$的直线交椭圆于$A,B$两点,$M$是点$A$关于原点的对称点.若 ...

  3. CS Academy Sliding Product Sum(组合数)

    题意 有一个长为 \(N\) 的序列 \(A = [1, 2, 3, \dots, N]\) ,求所有长度 \(\le K\) 的子串权值积的和,对于 \(M\) 取模. \(N \le 10^{18 ...

  4. Hdoj 1102.Constructing Roads 题解

    Problem Description There are N villages, which are numbered from 1 to N, and you should build some ...

  5. Leetcode 215. 数组中的第K个最大元素 By Python

    在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ...

  6. httpd配置

    HTTP:Hypertext Transfer Protocol: HTML:Hypertext Markup Language: URL:Uniform Resource Locator,在Inte ...

  7. 【WC2018】州区划分(FWT,动态规划)

    [WC2018]州区划分(FWT,动态规划) 题面 UOJ 洛谷 题解 首先有一个暴力做法(就有\(50\)分了) 先\(O(2^nn^2)\)预处理出每个子集是否合法,然后设\(f[S]\)表示当前 ...

  8. css- @media @font-face 的理解

    在我的博客园定制的css中有2个之前没有遇到的csss属性@font-face @media @media 在css文件中的使用如下 ` @media screen and (max-width: 1 ...

  9. urllib的实现---timeout,获取http响应码,重定向,proxy的设置

    1.Timeout设置超时 只能修改Socket设置全局Timeout #! /usr/bin/env python3 import socket import urllib.request # ti ...

  10. TypeError: __init__() got an unexpected keyword argument 't_command'

    python  .\manage.py migrate 报错如下 λ python .\manage.py migrateTraceback (most recent call last): File ...