UVA 12627 Erratic Expansion

        題目大致意思爲 告訴你一個紅球爲0時狀態,已知一個紅球每過一個時間會變爲文檔所示圖中的3紅1藍,而藍球每過一個時間則會變爲4個藍球。問在某一時刻,h1與h2之間的紅球有幾個。


       RT,這一題剛看到的時候毫無思路,仔細觀察圖後發現,發現肯定是遞歸。然後找遞歸公式。先說說我的想法歷程,不想看的可以直接到後面看結論。


ijjh[i][j]i,j
h[i][j]=h[i1][j>2i1?j2i1:j]2

    於是,我認爲直接從開始的地方加到結束即可。


    當然妥妥的超時。。。。。。


    於是想維護前綴和,發現也不容易。突然發現行的遞歸能寫,多半和的遞歸也能寫。

找了一段時間的規律後,得出

if(j>2i1)
s[i][j]=s[i][2i1]+s[i1][j2i1]
else
s[i][j]=s[i1][j]2

     合併一下第一行,得到

s[i][j]=s[i1][2i1]2+s[i1][j2i1]
又 發現
becauses[i][2i1]=3i12
故得出代碼

#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);
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章