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.