日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UVA 10518 How Many Calls?

發布時間:2023/12/9 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UVA 10518 How Many Calls? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

UVA_10518

??? 這個題目想到f(n)=f(n-1)+f(n-2)+1還是比較容易的,但如果能想到是f(n)=2*F(n)-1就不太容易了,在看了UVA的論壇之后我才知道原來可以表示成這個樣子,其中F(n)為斐波那契數,有了這個式子是第一步,后面的計算過程倒還不算麻煩。

? ? 后來在群里討論的時候,突然發現S(n)=F(n)+F(n+1)-1,S(n)為斐波那契的前n項和,這時又想到我之前推到的一個結論f(n)=S(n)-F(n-1),發現這個和f(n)=2*F(n)-1是可以轉化的,限于當時還不知道S(n)的表達式,所以錯過了推出結論的機會。

??? 先說說我推出f(n)=S(n)-F(n)的過程吧,我們在遞推計算遞歸次數的時候,每次的+1都另起一行來寫,這樣我們會得到下面的這個表。

? ? f(0) ? ? ?f(1) ? ? ?f(2) ? ? ?f(3) ? ? ?f(4) ? ? ?f(5) ? ? ?f(6)

???????????????????????????????????????????? ???????????????????1

????????????????????????????????????????????????????? 1???????? 1

??????????????????????????????????????????? 1???????? 1???????? 2

????????????????????????????????? 1???????? 1???????? 2???????? 3

??????????????????????? 1???????? 1? ???????2???????? 3???????? 5

??? 1???????? 1???????? 2???????? 3???????? 5???????? 8???????? 13

? ? 沒有數字的地方就可以看做是0,f(i)下面對應的整數和就是f(i)的值,相當于計算f(n)=f(n-1)+f(n-2)+1的時候,每行都進行f(n)=f(n-1)+f(n)的運算,最后再把1另起一行寫在上面。

? ? 這樣我們就能很明顯的看出來,每行都是一個斐波那契數列,不難得到f(n)=S(n)-F(n-1),這樣再把S(n)= F(n)+F(n+1)-1代入,就可以得到f(n)=2*F(n)-1。

? ? 不管用什么辦法,反正我們現在是得到f(n)的表達式了。下面回到題目,問題就轉化成了f(n)%b的值是多少,由于n很大所以我們在計算F(n)的時候不能直接遞推計算,于是可以把F(n)寫成矩陣的形式,然后用快速冪取模求得F(n)%b的值,進而就會有f(n)%b的值。

#include<stdio.h>
#include<string.h>
#include<math.h>
long long int N, B;
long long int a[100][5], b[5];
void pow_mod(long long int n, int e)
{
if(n == 1)
{
a[e][0] = a[e][1] = a[e][2] = 1;
a[e][3] = 0;
return ;
}
pow_mod(n / 2, e + 1);
a[e][0] = (a[e + 1][0] * a[e + 1][0] + a[e + 1][1] * a[e + 1][2]) % B;
a[e][1] = (a[e + 1][0] * a[e + 1][1] + a[e + 1][1] * a[e + 1][3]) % B;
a[e][2] = (a[e + 1][2] * a[e + 1][0] + a[e + 1][3] * a[e + 1][2]) % B;
a[e][3] = (a[e + 1][2] * a[e + 1][1] + a[e + 1][3] * a[e + 1][3]) % B;
if(n % 2)
{
b[0] = (a[e][0] * a[0][0] + a[e][1] * a[0][2]) % B;
b[1] = (a[e][0] * a[0][1] + a[e][1] * a[0][3]) % B;
b[2] = (a[e][2] * a[0][0] + a[e][3] * a[0][2]) % B;
b[3] = (a[e][2] * a[0][1] + a[e][3] * a[0][3]) % B;
a[e][0] = b[0], a[e][1] = b[1], a[e][2] = b[2], a[e][3] = b[3];
}
}
void solve()
{
a[0][0] = a[0][1] = a[0][2] = 1;
a[0][3] = 0;
if(N == 0)
{
printf("1\n");
return ;
}
pow_mod(N, 1);
printf("%lld\n", (2 * a[1][0] + B - 1) % B);
}
int main()
{
int t = 0;
for(;;)
{
scanf("%lld%lld", &N, &B);
if(!N && !B)
break;
printf("Case %d: %lld %lld ", ++ t, N, B);
solve();
}
return 0;
}


轉載于:https://www.cnblogs.com/staginner/archive/2011/12/14/2288187.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的UVA 10518 How Many Calls?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。