Problem D: qwb与神奇的序列
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 913 Solved: 109
[ Submit][ Status][ Web Board]
Description
qwb又遇到了一道题目:
有一个序列,初始时只有两个数x和y,之后每次操作时,在原序列的任意两个相邻数之间插入这两个数的和,得到新序列。举例说明:
初始:1 2操作1次:1 3 2
操作2次:1 4 3 5 2
……
请问在操作n次之后,得到的序列的所有数之和是多少?
Input
多组测试数据,处理到文件结束(测试例数量<=50000)。
输入为一行三个整数x,y,n,相邻两个数之间用单个空格隔开。(0 <= x <= 1e10, 0 <= y <= 1e10, 1 < n <= 1e10)。
Output
对于每个测试例,输出一个整数,占一行,即最终序列中所有数之和。
如果和超过1e8,则输出低8位。(前导0不输出,直接理解成%1e8)
如果和超过1e8,则输出低8位。(前导0不输出,直接理解成%1e8)
Sample Input
1 2 2
Sample Output
15
思路:
在纸上不难写出前几项:
①x*1+y*1
②x*2+y*2
③x*5+y*5
④x*14+y*14
⑤x*41+y*41
一开始看到前四项的时候感觉好尼玛666.这不就是卡特兰数吗。然后看了一眼数据范围直接GG.
觉得会有神一样的姿势求卡特兰数,然而发现很多人都会做,就觉得可能不是卡特兰数了,再推了一项,果然不是。
那么很显然,ans=(3^n+1)/2;
那么结果直接求一下就行。
注意一点:
这里需要/2去模,我们不能直接模。
又因为1e8不是素数,所以还不能求逆元。
感谢dalao的指导:
Ac代码:
#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
#define ll long long int
ll mod=100000000;
ll kuaisuji(ll a,ll b)
{
ll ans=0;
a%=mod;
while(b>0)
{
if(b%2==1)ans=(ans+a)%mod;
b/=2;
a=(a+a)%mod;
}
return ans;
}
ll poww(ll a,ll b)
{
ll tmp=a%mod;
ll ans=1;
ll n=b;
while(n)
{
if(n%2==1)
{
ans=(kuaisuji(ans,tmp))%mod;
n-=1;
}
else
{
tmp=(kuaisuji(tmp,tmp))%mod;
n/=2;
}
}
return ans;
}
int a,b,n;
int main(){
ll x,y,n;
mod*=2;
while(~scanf("%lld%lld%lld",&x,&y,&n))
{
ll tmp=(poww(3,n)+1)%mod;
printf("%lld\n",(tmp*(x+y))%mod/2);
}
return 0;
}