题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=6304
多校contest1
Problem Description

Chiaki is interested in an infinite sequence a1,a2,a3,..., which is defined as follows:

an={1an−an−1+an−1−an−2n=1,2n≥3

Chiaki would like to know the sum of the first n terms of the sequence, i.e. ∑i=1nai. As this number may be very large, Chiaki is only interested in its remainder modulo (109+7).

Input
There are multiple test cases. The first line of input contains an integer T (1≤T≤105), indicating the number of test cases. For each test case:
The first line contains an integer n (1≤n≤1018).
Output

For each test case, output an integer denoting the answer.

题目大意是求一个 奇怪序列的 前 n 项 和,n最坏情况达 1e18。
开始打了个表,发现在序列是从1开始的连续整数(每个整数出现的次数不同),除了数字 1是出现两次,其他数字 如x 都是出现 lowbit(x)后缀0的个数+1 次。 如2(10) 出现2次 ,3(11) 出现1次,4(100) 出现3次,5(101)出现1次,6(110) 出现2次...
可以发现这是一个十分有特点的(类似2进制,有部分对称性)的序列
接下来我们可以发现如果把1当做出现1次,出现在 2^n 上,如果占满 ,次数总和刚好是 2^(n+1) -1 次,那么多出来的数似乎又没有规律了,这时我们可以利用局部对称与这个和二进制相似的特点,找到 第 n 个数 是数字多少(落在图中的位置),
有两种方法:
第一种 可以知道N(自减一后)对应的准确数字,但不知N落在的数字差几次被填满,不便计算。
 1 void init(){
 2     P[0]=1;P[1]=2;
 3     nP[0]=0;nP[1]=1;
 4     for(int i=2;i<=62;++i){
 5         P[i]=2*P[i-1];
 6         nP[i]=P[i]-1;
 7     }
 8 }
 9
10 ll getbound(ll N){
11     ll bound=0;
12     for(int i=62;i>=1;--i){
13         while(N>=nP[i]){
14             N-=nP[i];
15             bound+=P[i-1];
16         }
17     }
18     return bound;
19 }

第二种 完全参照二进制,可知N(自减一后)所落在的数字最近的次数填满数字,后来计算时很方便。

 1 void init(){
 2     P[0]=1;P[1]=2;
 3     nP[0]=0;nP[1]=1;
 4     for(int i=2;i<=62;++i){
 5         P[i]=2*P[i-1];
 6         nP[i]=P[i]-1;
 7     }
 8 }
 9
10 ll getbound(ll& N){
11     ll bound=0;
12     for(int i=62;i>=1;--i){
13         if(N>=nP[i]){
14             N-=nP[i];
15             bound+=P[i-1];
16         }
17     }
18     return bound;
19 }

计算时可以可利用每个数字出现的次数,是1(2^0)的倍数的出现过一次,是2(2^1)的倍数的额外出现过一次,是4(2^2)的倍数的又额外出现一次,,,(这也恰恰是后缀0的意义)

在这里贴两份按照上述两种方法写的代码。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef long long ll;
 5
 6 const ll MOD=1e9+7;
 7 ll P[66];
 8 ll nP[66];
 9 ll a[101];
10 ll arr[101];
11
12 ll lowbit(ll x){
13     ll low=x&(-x);
14     ll cnt=0;
15     while(low>>=1){
16         cnt++;
17     }
18     return cnt;
19 }
20
21 void init(){
22     P[0]=1;P[1]=2;
23     nP[0]=0;nP[1]=1;
24     for(int i=2;i<=62;++i){
25         P[i]=2*P[i-1];
26         nP[i]=P[i]-1;
27     }
28
29     //a[1]=1;a[2]=1;
30     //arr[1]=1;arr[2]=2;
31     //for(int i=3;i<101;i++){
32     //    a[i]=a[i-a[i-1]]+a[i-1-a[i-2]];
33     //    arr[i]=arr[i-1]+a[i];
34     //}
35
36     //for(int i=1;i<101;++i) printf("%lld\n",arr[i]);
37
38 }
39
40 ll inv(ll a,ll m){
41     if(a==1) return 1;
42     return inv(m%a,m)*(m-m/a)%m;
43 }
44
45 ll getbound(ll N){
46     ll bound=0;
47     for(int i=62;i>=1;--i){
48         while(N>=nP[i]){
49             N-=nP[i];
50             bound+=P[i-1];
51         }
52     }
53     return bound;
54 }
55
56 int main(){
57     //freopen("data.in","r",stdin);
58     //freopen("data1.out","w",stdout);
59     init();
60     int T;
61     scanf("%d",&T);
62     while(T--){
63         ll N;
64         scanf("%lld",&N);
65         if(N==1) puts("1");
66         else{
67             ll ans=0;
68             N-=1ll;
69             ll bound=0;
70             bound=getbound(N);
71             //printf("bound = %lld\n",bound);
72             ll cnt=lowbit(bound)+1ll;
73             ll tot=N;
74             for(ll i=1;i<=cnt;++i){
75                 if(bound==getbound(N+i)) tot++;
76                 else break;
77             }
78             ll _m2=inv(2,MOD);
79             //printf("%lld\n",_m2);
80             for(int i=0;i<=62;++i){
81                 if(P[i]<=bound){
82                     ll M=bound/P[i];
83                     ans=(ans+(P[i]%MOD)*(M%MOD)%MOD*((M+1ll)%MOD)%MOD*_m2%MOD)%MOD;
84                 }
85                 else break;
86             }
87             //printf("1:%lld\n",(ans+1)%MOD);
88             ans=(ans-(bound)*(tot-N)%MOD+MOD)%MOD;
89             printf("%lld\n",(ans+1ll)%MOD);
90             //printf("%I64d %I64d\n",(ans+1ll)%MOD,arr[N+1]);
91             //最后加一
92         }
93     }
94     return 0;
95 }

View Code

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef long long ll;
 5
 6 const ll MOD=1e9+7;
 7 ll P[66];
 8 ll nP[66];
 9 ll a[101];
10 ll arr[101];
11
12 ll lowbit(ll x){
13     ll low=x&(-x);
14     ll cnt=0;
15     while(low>>=1){
16         cnt++;
17     }
18     return cnt;
19 }
20
21 void init(){
22     P[0]=1;P[1]=2;
23     nP[0]=0;nP[1]=1;
24     for(int i=2;i<=62;++i){
25         P[i]=2*P[i-1];
26         nP[i]=P[i]-1;
27     }
28
29     //a[1]=1;a[2]=1;
30     //arr[1]=1;arr[2]=2;
31     //for(int i=3;i<101;i++){
32     //    a[i]=a[i-a[i-1]]+a[i-1-a[i-2]];
33     //    arr[i]=arr[i-1]+a[i];
34     //}
35
36     //for(int i=1;i<101;++i) printf("%lld\n",arr[i]);
37
38 }
39
40 ll inv(ll a,ll m){
41     if(a==1) return 1;
42     return inv(m%a,m)*(m-m/a)%m;
43 }
44
45 ll getbound(ll& N){
46     ll bound=0;
47     for(int i=62;i>=1;--i){
48         if(N>=nP[i]){
49             N-=nP[i];
50             bound+=P[i-1];
51         }
52     }
53     return bound;
54 }
55
56 int main(){
57     //freopen("data.in","r",stdin);
58     //freopen("data1.out","w",stdout);
59     init();
60     int T;
61     scanf("%d",&T);
62     while(T--){
63         ll N;
64         scanf("%lld",&N);
65         if(N==1) puts("1");
66         else{
67             ll ans=0;
68             N-=1ll;
69             ll bound=0;
70             bound=getbound(N);
71             //printf("bound = %lld\n",bound);
72             //ll cnt=lowbit(bound)+1ll;
73             //ll tot=N;
74             //for(ll i=1;i<=cnt;++i){
75             //    if(bound==getbound(N+i)) tot++;
76             //    else break;
77             //}
78             ll _m2=inv(2,MOD);
79             for(int i=0;i<=62;++i){
80                 if(P[i]<=bound){
81                     ll M=bound/P[i];
82                     ans=(ans+(P[i]%MOD)*(M%MOD)%MOD*((M+1ll)%MOD)%MOD*_m2%MOD)%MOD;
83
84                 }
85                 else break;
86             }
87             //printf("1:%lld\n",(ans+1)%MOD);
88             ans=(ans+(bound+1)*N%MOD)%MOD;
89             printf("%lld\n",(ans+1ll)%MOD);
90             //printf("%I64d %I64d\n",(ans+1ll)%MOD,arr[N+1]);
91             //最后加一
92         }
93     }
94     return 0;
95 }

View Code

然后,比赛时WA了两发,其实规律找到了,但错在了计算,算总和时,第一个错误处是没用逆元,第二个错误处是P[i]在N为1e18时奇大,应该先mod在相乘。

血的教训。

Chiaki is interested in an infinite sequence a1,a2,a3,..., which is defined as follows:

an={1an−an−1+an−1−an−2n=1,2n≥3

Chiaki would like to know the sum of the first n terms of the sequence, i.e. ∑i=1nai. As this number may be very large, Chiaki is only interested in its remainder modulo (109+7).

转载于:https://www.cnblogs.com/Kiritsugu/p/9363002.html

HDU 6304 Chiaki Sequence Revisited相关推荐

  1. HDU 6304 Chiaki Sequence Revisited(找规律)

    题目链接:Chiaki Sequence Revisited 题意 定义一个序列 an={1an−an−1+an−1−an−2n=1,2n≥3an={1n=1,2an−an−1+an−1−an−2n≥ ...

  2. HDU 6304 Chiaki Sequence Revisited(二分+找规律)

    题目链接 Chiaki Sequence Revisited Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  3. [HDU-6304] Chiaki Sequence Revisited

    Chiaki Sequence Revisited http://acm.hdu.edu.cn/showproblem.php?pid=6304 an={1an−an−1+an−1−an−2n=1,2 ...

  4. HDU 1005 Number Sequence

    [题目]                                                   Number Sequence Time Limit: 2000/1000 MS (Jav ...

  5. HDU 5400 Arithmetic Sequence

    HDU 5400 Arithmetic Sequence /** HDU 5400 Arithmetic Sequence 直接预处理求解就好了 预处理找出以a[i]结尾最长的subArr长度(满足条 ...

  6. HDU.1005 Number Sequence

    原题 HDU.1005 Number Sequence 分类 杂题 题意 给定一个数列{an}\left\{ a_n \right\}{an​}的前两项a1a_1a1​.a2a_2a2​,以及其递推公 ...

  7. HDU 1560 DNA sequence(DNA序列)

    HDU 1560 DNA sequence(DNA序列) Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K  ...

  8. HDU 1711 Number Sequence(KMP算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Number Sequence Time Limit: 10000/5000 MS (Java/ ...

  9. 牛客网暑期ACM多校训练营(第三场): C. Chiaki Sequence Reloaded(数位DP)

    题目描述 Chiaki is interested in an infinite sequence a1, a2, a3, ..., which defined as follows: Chiaki ...

最新文章

  1. SVG和canvas
  2. 用VB.net开发.NET Micro Framework
  3. 虚指针的用法(原出处//http://blog.csdn.net/haoel/article/details/1948051)
  4. spring aop 注入源码解析 1
  5. 前端常用效果(2)带效果的tab切换
  6. python判断几个数最大最小_python 找出list中最大或者最小几个数的索引方法
  7. [Windows]_[0基础]_[使用命令行工具dumpbin分析文件]
  8. leetcode503. 下一个更大元素 II
  9. 扩大swap分区--Ubuntu手记之系统配置
  10. 快速开发工作流_01_简单流程案例
  11. 字符串匹配(二)——逆向思维 BMH
  12. java 读文件 解析
  13. [python3] zipfile压缩目录下所有的文档都被压缩,并解决压缩路径过深的问题
  14. Agilent GeneSpring GX V11.5_win32_win64扩展生物学分析软件
  15. 免费U盘数据恢复软件有哪些,如何免费恢复U盘的数据
  16. Excel数字小写金额转换汉字大写金额公式的简单设置
  17. AXURE RP8实战手册 网站和APP原型制作案例精粹
  18. python 控制手机摄像头_用Python获取摄像头并实时控制人脸 !
  19. robocup2D教程
  20. 英国诺丁汉大学的AIMS与虚拟现实技术

热门文章

  1. sql server 2005 T-SQL CEILING (Transact-SQL)
  2. 将在2021年改变商业格局的10项技术
  3. AI时代的摩尔定律?黄氏定律预测AI性能将逐年翻倍
  4. Windows XP安装Python,最高支持到3.4.4,后续版本不支持
  5. 天津将规划新增津雄城际铁路 建15分钟京津冀生活圈
  6. FPGA实验四——时间基准电路和带使能的多周期计数器
  7. centos java程序_刚得到一台centos7服务器,作为Java程序员应该做的事
  8. MQ和RabbitMQ作用特点
  9. mapper中 <include refid=“XXX“></include>标签 <sql id=“XXX“>标签
  10. json数组 js html标签,JS 实现创建HTML标签及解析Json