我們按以下方式產生序列:
1、 開始時序列是: 「1」 ;
2、 每一次變化把序列中的 「1」 變成 「10」 ,」0」 變成 「1」。
經過無限次變化,我們得到序列」1011010110110101101…」。
總共有 q 個詢問,每次詢問為:在區間a和b之間有多少個1。
任務 寫乙個程式回答q個詢問
輸入 第一行為乙個整數q,後面有q行,每行兩個數用空格隔開的整數a, b。
輸出 共q行,每行乙個回答
約定 • 1 <= q <= 5000
• 1 <= a <= b < 2^63
可以很容易的發現,長度和1的個數都是斐波那契數列序列 長度 1的個數
1 1 1
10 2 1
101 3 2
10110 5 3
10110101 8 5
1011010110110 13 8
…… ……
然後每乙個序列s[i]=s[i-1]+s[i-2]
然後可以想到用遞迴(然而我並沒有想到)。
對於每乙個序列s[i],我們都可以把它分割成s[i-1]和s[i-2],然後s[i-2]繼續分割成s[(i-2)-1]和s[(i-2)-2]……最後s被分成很多個長度和1的個數在變化之內的序列,這些序列1的個數相加,ans[b]-ans[a-1]即答案。
注意資料有點大,可以qword(無符號的整型0~2^64-1)
const
maxn=92;
var n,i:longint;
t,b:qword;
a,f:array[0..105]of qword;
function
dfs(x:qword;i:longint):qword;
begin
if (x=0) then
exit(0);
if (x=a[i]) then
exit(f[i]);
if x>a[i-1] then dfs:=dfs(x-a[i-1],i-2)+f[i-1]
else dfs:=dfs(x,i-1);
end;
begin
readln(n);
a[0]:=1;a[1]:=1;
f[0]:=0;f[1]:=1;
for i:=2
to maxn do
begin
a[i]:=a[i-1]+a[i-2];
f[i]:=f[i-1]+f[i-2];
end;
for i:=1
to n do
begin
readln(t,b);
writeln(dfs(b,maxn)-dfs(t-1,maxn));
end;
end.
SSL 1861 無限序列
有乙個序列,初始狀態是 1 每次都可以讓序列中的 1 變成 10 讓 0 變成 1 最後可以得到 1011010110110101101.求這個序列的a到b中一共有多少個 1 找規律可以發現這個字串每次操作都是加上前兩次的字串,類似斐波那契的演算法,例如 101 是從 10 1 得來的,下乙個字串就...
字首和 無限序列
我們按以下方式產生序列 1 開始時序列是 1 2 每一次變化把序列中的 1 變成 10 0 變成 1 經過無限次變化,我們得到序列 1011010110110101101 總共有 q 個詢問,每次詢問為 在區間a和b之間有多少個1。任務 寫乙個程式回答q個詢問 第一行為乙個整數q,後面有q行,每行兩...
模擬 無限序列
題目描述 我們按以下方式產生序列 1 開始時序列是 1 2 每一次變化把序列中的 1 變成 10 0 變成 1 經過無限次變化,我們得到序列 1011010110110101101 總共有 q 個詢問,每次詢問為 在區間a和b之間有多少個1。任務 寫乙個程式回答q個詢問 輸入 第一行為乙個整數q,後...