題目大致意思爲 告訴你一個紅球爲0時狀態,已知一個紅球每過一個時間會變爲文檔所示圖中的3紅1藍,而藍球每過一個時間則會變爲4個藍球。問在某一時刻,h1與h2之間的紅球有幾個。
RT,這一題剛看到的時候毫無思路,仔細觀察圖後發現,發現肯定是遞歸。然後找遞歸公式。先說說我的想法歷程,不想看的可以直接到後面看結論。
於是,我認爲直接從開始的地方加到結束即可。
當然妥妥的超時。。。。。。
於是想維護前綴和,發現也不容易。突然發現行的遞歸能寫,多半和的遞歸也能寫。
找了一段時間的規律後,得出
合併一下第一行,得到
又 發現
故得出代碼
#include <stdio.h>
#define LL long long
LL QWQ[31];
LL QOQ[31];
LL QAQ(int i,int j){
if(j==0)
return 0;
if(i==0&&j==1)
return 1;
if(j>QWQ[i-1])
return (QOQ[i-1]<<1)+QAQ(i-1,j-QWQ[i-1]);
else
return QAQ(i-1,j)<<1;
}
int main(){
//a[i][j]=a[i-1][j>2^(i-1)?j-2^(i-1):j]*2
/*
*
* if(j>2^(i-1))
* a[i][j]=a[i-1][j-2^(i-1)]
* else
* a[i][j]=a[i-1][j]*2
* a[i][j]=a[i-1][]
jmax=2^i;
if(j>2^(i-1))
s[i][j]=s[i][2^(i-1)]+s[i-1][j-2^(i-1)]
else
s[i][j]=s[i-1][j]*2
s[i][j]=s[i-1][2^(i-1)]*2+s[i-1][j-2^(i-1)]
because s[i][2^(i-1)]=3^(i-1)*2
*/
//freopen("data.txt","r",stdin);
//freopen("datas.txt","w",stdout);
QWQ[0]=1;QOQ[0]=1;
for(int i=1;i<31;i++)
QWQ[i]=QWQ[i-1]*2;
for(int i=1;i<31;i++)
QOQ[i]=QOQ[i-1]*3;
int T;
scanf("%d",&T);
int times=0;
while(T--){
times++;
int k,a,b;
LL sum=0;
scanf("%d %d %d",&k,&a,&b);
sum=QAQ(k,b)-QAQ(k,a-1);
printf("Case %d: ",times);
printf("%lld\n",sum);
}
}