4247 奇特的生物
時間限制: 1 s
空間限制: 128000 kb
題目等級 : 鑽石 diamond
題解題目描述 description
科學家們最近發現了一種奇怪的生物,它們每天長大一歲,剛出生的寶寶為1歲,且它們的年齡沒有上限。已知年齡為1歲,2歲,3歲,……,k歲的個體具有生育能力,當年齡為i的具有生育能力的個體將長大一歲時會生下ai個1歲的幼崽。假設第一天只有乙個年齡為1的幼崽,現在科學家們想知道第x天年齡為y的個體有多少,但由於該物種增長速度太快,於是他們將這個任務交給了你。由於這個數可能很大,你需要對p取模。
輸入描述 input description
輸入資料第一行給定四個整數k,x,y,p。
第二行包括k個整數,第i個整數代表ai。
輸出描述 output description
輸出資料報含一行,表示第x天年齡為y的個體的數量對p取模後的結果。
樣例輸入 sample input
【樣例輸入 1】
3 3 1 1007
1 1 1
【樣例輸入 2】
3 6 2 1007
1 2 1
樣例輸出 sample output
【樣例輸出1】
2【樣例輸出 2】
13增加乙個新樣例。codevs上的第十個點。
莫名其妙的矩陣快速冪解決不了。
樣例輸入3:
10 10258496531232 52 700000000017
5 89 63 25 48 76 95 23 15 25
樣例輸出3:
611559827774
分析:這道題輕輕一想發現。哦。可以用遞推來模擬。遞推公式大致應該是這個樣子的。
由題意可知。每個年齡的數量都是由上個年齡的人長成這個年齡的。而只有1歲的人是靠1-k有生育能力的人生產出來的。
由於這個範圍很大。所以很容易讓人想到用矩陣乘法來對這個進行遞推優化。
但是仔細一想。發現這道題有個性質。就是沒個人數都是由上乙個轉化過來的,那麼。其實當f[1]產生的時候。以後的數量就是確定的。所以我們就沒必要把全部的情況都存下來。就存1-k,每次進行狀態轉移就好。其次我們會發現。在整個序列裡。因為只有f[1]在變所以我們求 x天y歲人數的問題就轉換成了。我們求 x-y+1天1歲的人數問題。為什麼呢?。我們y歲人數起時在底x-y+1天就轉化好了。而之後剩下的天數,就是將x-y+1天1歲的人轉移轉移到x天y歲。
接下來的問題就剩到了,如何建立矩陣之後用矩陣來快速冪一些奇怪的事情。
這個矩陣很顯然易見的解決這個問題。因為矩陣乘法是第乙個舉證的行乘第二個的列。所以我們在這裡矩陣a第一行就是將f[1~k]裡的所有結果相加。之後的行就完成了乙個轉移的工作。將上一天轉換到當前天數。
於是就是將整個矩陣乘上 x-y 次。求a[1][1]--代表第x-y+1天的一歲的人數。
還有既然都是乘x-y次那麼我們就要對(y>x)的情況進行特判。還有就是要加上快速乘法。不然第10個點過不去。這個資料就專門來卡你。
貼上**。
#include#include#includeusing namespace std;long long int mod,k,x,y;
struct node
}a,ans;
long long mul(long long x, long long y)
return ret;
}node operator*(node a,node b)
}return res;
}int main()
if(x>=1 ,a=a*a)
printf("%lld",ans.l[1][1]);
return 0;
}
《奇特的一生》
這是一部寫真人真事的文獻性 講的是蘇聯昆蟲學家柳比歇夫獻身科學的故事。從 1916 年元旦開始,二十六歲的柳比歇夫便實行一種 時間統計法 他每天都要核算自己的時間,一天一小結,每月一大結,年終一總結。直到 1972 年他去世的那一天,56 年如一日,從不間斷。柳比歇夫在短促的一生中取得了豐碩的科學成...
奇特的一生 筆記
時間開銷日記的格式是 日期 事件 花費時間,每天記錄5 7行 我們一生的時間,大部分用於錯誤及種種惡行 很大一部分虛拋浪擲,無所事事。我們整個一生,幾乎都沒有用來幹應當幹的事 想方設法利用每一分鐘,利用任何所謂的 時間下腳料 乘電車 坐火車 開會 排隊 時間下腳料 的利用,出門旅行,看小部頭的書,學...
04 奇特的一生(筆記)
了解乙個人,就要看到他的矛盾。他的時間統計法不是乙個節儉的計畫工作者的預算,吧他的時間統計法比作想向時間做自我剖析更為恰當。存在著兩種職責 一種是科學,另一種是對某一歷史時期某門科學某一分支的狀況所負的責任。我不信,第二種職責就比第一種更為重要。是第一種職責在其決定性作用。正式第一種職責 發明 重大...