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. Get Luffy Out * HDU - 1816(2 - sat 妈的 智障)

    题意: 英语限制了我的行动力....就是两个钥匙不能同时用,两个锁至少开一个 建个图 二分就好了...emm....dfs  开头low 写成sccno  然后生活失去希望... #include & ...

  2. 【UOJ349】【WC2018】即时战略 LCT 动态点分治

    这是一道交互题 题目大意 有一棵\(n\)个点的树.最开始\(1\)号点是白的,其他点是黑的. 每次你可以执行一个操作:\(explore(x,y)\).要求\(x\)是一个白点.该函数会返回从\(x ...

  3. 自学Python4.5-装饰器举例

    自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Pyth ...

  4. 自学华为IoT物联网_09 OceanConnect业务流程

    点击返回自学华为IoT物流网 自学华为IoT物联网_09 OceanConnect业务流程 1.  物流网重要的连个协议介绍 1.1  重要物联网协议介绍----MQTT MQTT(消息队列遥测传输) ...

  5. 【mysql】mysql索引及优化学习

    一般优化mysql首先看查找的数据有没有用到索引,没有索引就加索引,有索引时候避免索引失效.(如果优化器觉得不需要索引就能返回所需要的数据暂不考虑) 看下面两条语句 MySQL [release_te ...

  6. tvs二极管应用电路

    瞬态电压抑制器(TVS)具有响应时间快.瞬态功率大.漏电流低.击穿电压偏差小.箝位电压较易控制.无损坏极限.体积小等优点.目前已广泛应用于计算机系统.通讯设备.交/直流电源.汽车.家用电器.仪器仪表等 ...

  7. request.getRequestDispatcher 页面跳转,样式丢失。

    在页面中引用样式和其它资源的时候,尽量不要用相对路径,因为"当前路径"这个概念在J2EE中是不稳定的. 所以最好都是绝对路径,类似于: <% String cp = requ ...

  8. 【转】服务化框架技术选型与京东JSF解密

    [京东技术]声明:本文转载自微信公众号“开涛的博客”,转载务必声明. 作者:章耿,原京东资深架构师,曾负责京东服务框架,配置中心等基础平台.近十年工作经验,专注于基础中间件等底层技术架构,对分布式系统 ...

  9. vue--传值

    传值:(如果传的是引用类型,当值发生改变时所有绑定他的全都发生改变,如果传的时值类型,就只有他自己发生改变) 父传子: 父页面:父组件定义一个属性 users:[ {name:'张三',positio ...

  10. Django 跨域请求

    跨域:通过js或python在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(Django)的数据.只要协议.域名.端口有任何一个不同,都被 ...