第一题:无限序列(提高组第一试2011年10月21日)(2011年NOIP冲刺模拟试题)
来源:互联网 发布:xp禁止自动安装软件 编辑:程序博客网 时间:2024/05/21 15:47
我们按以下方式产生序列:
1、开始时序列是:"1" ;
2、每一次变化把序列中的"1"变成"10","0" 变成 "1"。
经过无限次变化,我们得到序列"1011010110110101101..."。
总共有Q个询问,每次询问为:在区间A和B之间有多少个1。
任务:写一个程序回答Q个询问。
【输入】
第一行为一个整数Q,后面有Q行,每行两个数用空格隔开的整数a, b。
【输出】
共Q行,每行一个回答。
【样例输入】
1
2 8
【样例输出】
4
【数据范围】
对于30%的数据,1<=Q<=20,1<=a<=b<10000;
对于100%的数据,1<=Q<=5000,1<=a<=b<2^63;
我们先看看序列变化规律,S1 = "1", S2 = "10", S3 = "101", S4 = "10110", S5 = "10110101", 等等. Si 是 S(i+1)的前缀。
序列Si 是由序列 S(i-1) 和 S(i-2), 连接而成的。
即Si = S(i-1)+S(i-2)(实际上是Fibonacci数列)。
设F[i]表示第i个序列的(长度)位数,G[i]表示第i个序列中“1”的个数。 如果要求的区间端点恰好是某个F[i],则可以直接返回此时的G[i]。例如,当a=1,b=13时,F[6]=13,则序列中G[6]=8个“1”。如果区间的端点不是某个F[i], 需要发现的规律是:如果a=F[i]+F[j]+F[k],则区间[1,a]中“1”的个数为G[i]+G[j]+G[k]。
例如,a=31时,a=F[7]+F[5]+F[2]=21+8+2,则区间中“1”的个数为:
13 + 5 + 1 = 19
找到规律后,我们可以用递归的方法求出任意长度的序列中“1”的个数。在计算闭区间[a, b]中“1”的个数时,用区间[1,b]的结果减去区间[1,a-1]的结果。这是一个常用的技巧。
我们先看看序列变化规律,S1 = "1", S2 = "10", S3 = "101", S4 = "10110", S5 = "10110101", 等等. Si 是 S(i+1)的前缀。
序列Si 是由序列 S(i-1) 和 S(i-2), 连接而成的。
即Si = Si-1 + Si-2 (实际上是Fibonacci数列)。
设F[i]表示第i个序列的(长度)位数,G[i]表示第i个序列中“1”的个数。 如果要求的区间端点恰好是某个F[i],则可以直接返回此时的G[i]。例如,当a=1,b=13时,F[6]=13,则序列中G[6]=8个“1”。如果区间的端点不是某个F[i],mj 需要发现的规律是:如果a=F[i]+F[j]+F[k],则区间[1,a]中“1”的个数为G[i]+G[j]+G[k]。
例如,a=31时,a=F[7]+F[5]+F[2]=21+8+2,则区间中“1”的个数为:
13 + 5 + 1 = 19
找到规律以后,我们可以用递归的方法求出任意长度的序列中“1”的个数。在计算闭区间[a, b]中“1”的个数时,是用区间[1,b]的结果减去区间[1,a-1]的结果。这是一个常用的技巧,希望能记着用。
我的代码:
/****************************************************************************************************** ** Copyright (C) 2011.07.01-2013.07.01 ** Author: famousDT <13730828587@163.com> ** Edit date: 2011-10-23******************************************************************************************************/#include <stdio.h>#include <stdlib.h>//abs,atof(string to float),atoi,atol,atoll#include <math.h>//atan,acos,asin,atan2(a,b)(a/b atan),ceil,floor,cos,exp(x)(e^x),fabs,log(for E),log10#include <vector>#include <queue>#include <map>#include <time.h>#include <set>#include <list>#include <stack> #include <string>#include <iostream>#include <assert.h>#include <string.h>//memcpy(to,from,count#include <ctype.h>//character process:isalpha,isdigit,islower,tolower,isblank,iscntrl,isprll#include <algorithm>using namespace std;typedef unsigned long long ll;#define MY_PI acos(-1)#define MY_MAX(a, b) ((a) > (b) ? (a) : (b))#define MY_MIN(a, b) ((a) < (b) ? (a) : (b))#define MY_MALLOC(n, type) ((type *)malloc((n) * sizeof(type)))#define MY_ABS(a) (((a) >= 0) ? (a) : (-(a)))#define MY_INT_MAX 0x7fffffff#define LOW_BIT(a) ((a) & (-(a)))//last none zero value/*==========================================================*\| \*==========================================================*/#define MAX 100 - 8ll x[MAX],y[MAX];ll process(ll a, ll carry){if (a == 0) return 0;if (a == x[carry]) return y[carry];if (a < x[carry]) return process(a, --carry);return process(a - x[carry], carry - 2) + y[carry];}int main(){ FILE *in, *out; in = fopen("infinit.in", "rt"); out = fopen("infinit.out", "wt");ll a, b;int i;x[1] = 1;x[2] = 2;y[1] = y[2] = 1;for (i = 3; i <= MAX; ++i) {x[i] = x[i - 1] + x[i - 2];y[i] = y[i - 1] + y[i - 2];//printf("%25llu%25llu\n", x[i], y[i]);}//printf("%25.0lf\n", pow(2.0, 63) - 1);//9223372036854775800int q;scanf("%d", &q);while (q--) {scanf("%llu%llu", &a, &b);ll ans = process(b, MAX - 1) - process(a - 1, MAX - 1);printf("%llu\n", ans);} fclose(in); fclose(out); return 0;}
- 第一题:无限序列(提高组第一试2011年10月21日)(2011年NOIP冲刺模拟试题)
- 第二题:引爆炸弹(提高组第一试2011年10月21日)(2011年NOIP冲刺模拟试题)
- 【*】第三题:收费站(提高组第一试2011年10月21日)(2011年NOIP冲刺模拟试题)(
- 第一题:奇怪的贸易(提高组第二试2011年10月22日)(2011年NOIP冲刺模拟试题)
- 第二题:游戏(提高组第二试2011年10月22日)(2011年NOIP冲刺模拟试题)
- 【*】第三题:保龄球(提高组第二试2011年10月22日)(2011年NOIP冲刺模拟试题)
- noip模拟赛第一题单词(7月26日)
- xjoi10月17日noip提高组模拟题
- 模拟(玩具谜题NOIP 2016 提高组 Day 1 第一题vijos2003)
- 2011年2月21日第一堂课(新来的老师哦!!!)
- 第一个JDBC程序-2011年09月13日
- 玩具装箱(noip冲刺模拟题——DP)
- SSL2836 2017年11月4日提高组T2 序列(迭代dfs)
- NOIP 2011 提高组第一试 铺地毯
- NOIP 2011 提高组第一试 铺地毯
- NOIP 2011 提高组第一试 选择客栈
- NOIP 2011 提高组第一试 选择客栈
- 【模拟赛】qbxt金秋冲刺训练营杯NOIP模拟赛第一场总结
- Session实例:一次性验证码
- HDOJ 2049 不容易系列之(4)——考新郎
- android横竖屏切换、键盘推出状态改变的处理
- Marty Cagan:产品管理与软件开发的关系
- Jquery AJAX POST和GET区别
- 第一题:无限序列(提高组第一试2011年10月21日)(2011年NOIP冲刺模拟试题)
- Windows Forms DataGridView 中合并单元格
- 顺序表的各种操作(建立,查找,删除,插入等)
- NullPointerException at org.apache.nutch.fetcher.FetcherOutputFormat.checkOutputSpecs
- 学习娱乐一点经验
- 遍历List<String[]>并 转换为String[][],List<List<String>>,Map<String,String[]>
- android Toast大全(五种情形)建立属于你自己的Toast
- flex中文本去前后空格
- Robert边缘检测算子的程序。换做其他算子,只要该其中的一个矩阵就行了