HDU2065 紅色病毒 問題 數學

2021-10-03 03:26:45 字數 3275 閱讀 4741

problem description

醫學界發現的新病毒因其蔓延速度和internet上傳播的"紅色病毒"不相上下,被稱為"紅色病毒",經研究發現,該病毒及其變種的dna的一條單鏈中,胞嘧啶,腺嘧啶均是成對出現的。

現在有一長度為n的字串,滿足一下條件:

(1) 字串僅由a,b,c,d四個字母組成;

(2) a出現偶數次(也可以不出現);

(3) c出現偶數次(也可以不出現);

計算滿足條件的字串個數.

當n=2時,所有滿足條件的字串有如下6個:bb,bd,db,dd,aa,cc.

由於這個資料肯能非常龐大,你只要給出最後兩位數字即可.

input

每組輸入的第一行是乙個整數t,表示測試例項的個數,下面是t行資料,每行乙個整數n(1<=n<2^64),當t=0時結束.

output

對於每個測試例項,輸出字串個數的最後兩位,每組輸出後跟乙個空行.

sample input41

420113

142460

sample output

case 1: 2

case 2: 72

case 3: 32

case 4: 0

case 1: 56

case 2: 72

case 3: 56

分析看他給的資料每個資料最多可以到264,而且還有多組資料,說明log(n)的演算法肯定是不行了,也就是說不能從1掃瞄到n,所以考慮直接通過n求出最後的答案。

同樣的,我們嘗試找一下規律,

當n = 1時,有兩種情況,b 和 d

當n = 2時,有六種情況,bb , bd , db , dd , aa 和 cc

實際上這裡發現b和d應該是同一種東西(但aa和cc不應該視作同一種東西,它能夠出現bdbd的情況,也能出現acac的情況),

有n個位置能放的話,那麼就沒有a和c的情況下,就有2n個方案,因為a和c的總和必須是偶數,然後我想到的是從n中拿出偶數個放上a和c,剩下的放上b和d。我嘗試寫出寫出了以下式子,

當n = 4時,ans = 24 + c4

2 * 2 * 22 + c4

4 * 23 * 20

在n = 4 的情況下,我就把情況分成了三種,

沒有a和c的情況,只有b和d,那麼就應該是24種

有兩個a和c,那麼只能是aa或cc兩種,剩下的兩個也有22種排列,所以那就是c4

2 * 2 * 22種情況

都是a和c,那麼就可以組合出aacc , acac , caca, ccaa,aaaa , cccc , acca , caac八種情況,實際上就是2n-1種情況(這裡分析見文末)

再把上述幾種情況加起來就得到了 ans = 72 的結論,發現和題目給的是一樣的,然後我又算了乙個當n = 6的情況,同樣和題目給的條件符合。抽象出公式,

ans = 2n + cn

2 * 21 * 2n-2 + cn

4 * 23 * 2n-4 + … + cn

n * 2n-1 * 2n-n

然後發現算式能夠化簡成為,

ans = 2n + 2n-1 * (cn

2 + cn

4 + … + cn

n-2 + cn

n)

後面的組合數還能夠再次化簡,

ans = 2n + 2n-1 * (2n-1 - 1)

所以,ans = 2n + 22n-2 - 2n-1

ans = 4n-1 + 2n-1

然後題目要求出ans的最後兩位,我們知道ab末尾兩位是迴圈的,這裡列出迴圈節,2n = [1,2,4,8,16,32,64,28,56,12,24,48,96,92,84,68,36,72,44,88,76,52,4,8,16,32,64,28,56,12],後面都是迴圈前面的內容,因此2n-1末尾兩個數字可以在o(1)的時間求得。同理,4n = [1,4,16,64,56,24,96,84,36,44,76,4,16,64,56,24],4n的數值也可以在o(1)求得。

所以在這裡,能夠直接通過題目給的數字n求得答案,時空複雜度都是o(1)。我當時怎麼就沒想到快速冪,快速冪似乎也挺方便的喂

完整**如下,

#include

using

namespace std;

typedef

long

long ll;

ll a[66]

,b[30];

intcalcn

(ll n)

intmain()

for(

int i =

10; i <

20; i++

)int e;

while(~

scanf

("%d"

,&e)

,e)puts(""

);}return0;

}

先打表直接出結果,這裡還遇到乙個大坑,迴圈節交接的地方出現了乙個很大的問題,除錯了一段時間才發現,221末尾兩位是52 而不是2,所以乾脆直接加了個特判,並且設定了迴圈節移位計算,之後每一次直接呼叫函式出結果。

當時也想到了兩個迴圈節函式相加,那麼所得的答案也應該有迴圈節,乙個迴圈節20乙個迴圈節10,所以實際上最後的答案也有個迴圈節是20…所以只要從1寫到30就能發現這個規律了吧那可能要算死。

然後再來想想對於n位長度,都是a和c並且a和c必須是偶數(可以為零),他應該有多少種可能性,

用n = 4舉例,

首先在4中選出0個a,那麼剩下都是c,這是一種情況

然後在4中選出2個a,那麼還有2個c,這就有c4

2種情況

最後在4中選出4個a,那麼沒有c,這又是一種情況

推廣到n,算式應該如下

idx = cn

0 + cn

2 + cn

4 + … + cn

n = 2n-1

這個idx就是最上面式子中

ans = 2n + cn

2 * 21

* 2n-2 + cn

4 * 23

* 2n-4 + … + cn

n * 2n-1

* 2n-n

至此這道題就算解完了。

hdu 2065 紅色病毒 問題

複習母函式,發現這道題可以用矩陣快速冪。然後做了一下 母函式 看起來好複雜的樣子 列dp方程,構造矩陣 dp n dp i 0 表示放到了第i位,前i位中有 偶數個a,有 偶數個c dp i 1 表示放到了第i位,前i位中有 奇數個a,有 偶數個c dp i 2 表示放到了第i位,前i位中有 偶數個...

hdu 2065 紅色病毒 問題

problem description 醫學界發現的新病毒因其蔓延速度和internet上傳播的 紅色病毒 不相上下,被稱為 紅色病毒 經研究發現,該病毒及其變種的dna的一條單鏈中,胞嘧啶,腺嘧啶均是成對出現的。現在有一長度為n的字串,滿足一下條件 1 字串僅由a,b,c,d四個字母組成 2 a出...

hdu2065 紅色病毒 問題

思路 先暴力打個表,然後找規律.include includeint main int b 5 4 int64 n,m while scanf d t eof t printf n return 0 description 醫學界發現的新病毒因其蔓延速度和internet上傳播的 紅色病毒 不相上下...