JZOJ 4.1 B组 无限序列

Description

  我们按以下方式产生序列:   
  1、 开始时序列是: “1” ;   2、 每一次变化把序列中的 “1” 变成 “10” ,”0” 变成 “1”。   经过无限次变化,我们得到序列”1011010110110101101…”。   总共有 Q 个询问,每次询问为:在区间A和B之间有多少个1。   任务:写一个程序回答Q个询问

Input

  第一行为一个整数Q,后面有Q行,每行两个数用空格隔开的整数a, b。

Output

  共Q行,每行一个回答

Sample Input

1

2 8

Sample Output

4

Data Constraint

【数据范围】 1 <= Q <= 5000

1 <= a <= b < 2^63


一种类似于斐波那契的东西
先用一个z来存前缀和
再求这个数列包含多少个1


代码如下:

var   n,i:longint;
      x,y:int64;
      z:array[-1..91] of int64;

function find(l:int64;k:longint):int64;
begin
  if l=0 then exit(0);
  find:=0;
  if l=z[k] then find:=z[k-1]else if l<=z[k-1] then find:=find(l,k-1) else find:=z[k-2]+find(l-z[k-1],k-2);
end;

begin
  readln(n);
  z[0]:=1;
  z[1]:=1;
  for i:=2 to  91 do z[i]:=z[i-1]+z[i-2];
  for i:=1 to n do
    begin
      read(x,y);
      writeln(find(y,91)-find(x-1,91));
    end;
end.
posted @ 2017-04-02 10:46  BEYang_Z  阅读(195)  评论(0编辑  收藏  举报