HDU 5459 Jesus Is Here 2015沈阳区域赛网络赛1010题

斐波那契数列的应用,然后就是无尽的推公式,其实不难推

然而,不熟悉C的取模运算,坑了我了。过了样例之后wa了好几次不知其果,后来试验发现有些输入(比如n=27)得到的输出是个离奇的负值。然后我们就以为是溢出了。

然而比赛结束之后仔细一想。TMD这不会溢出啊!不会爆long long 啊!

然而我们围绕着溢出想了好久。

结果是什么呢。。取模的时候需要加一个mod以防止负值出现,因为只要公式推对了,得到负值是由于途中不断取模且涉及到减法运算所致。另外,为什么加上mod就可以避免负值?据我们现在的理解,C语言处理负数对正数取模的时候,是本着让商尽量大的原则,这时候它取的结果往往就诡异了。。这个处理同数学不一样,而且,即便是负值,其绝对值也是小于mod的,这个不难理解。

所以对可能出现负值,而我们要取正数解的情况,我们加上一个mod再对mod取模。

公式怎么推得呢。。慢慢推,里面全是斐波那契数列在捣乱。所以先预处理出一张斐波那契数列的前201314项对mod取余的余数表。再根据这个应用到公式中,

答案公式也是递推形式给出的,因此也是自底向上求解比较好。同样可以放到预处理里面,然后直接打表即可

code:(PS:最重要的公式让我写残了,mod了一大片,有的是比赛时没多想加上去的,就先不简化了。。)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<algorithm>
#include<cstdlib>
#define maxn 201314
#define inf 0x3f3f3f3f
#define LL long long
#define top 33000
#define mod 530600414
using namespace std;
int t;
int n;
LL f[201315]= {0};
LL sum[201315];
LL ans[201315];
int a[110];

void init()
{
    f[0]=f[1]=1;
    for(int i=2; i<maxn; i++)
    {
        f[i]=(f[i-1]%mod+f[i-2]%mod)%mod;
    }
}
void init2()
{
    sum[1]=sum[2]=sum[3]=0;
    sum[4]=2;
    for(int i=5; i<=maxn; i++)
    {
        sum[i]=((sum[i-1]%mod+sum[i-2]%mod)%mod+(1LL*(f[i-4]%mod)*1LL*(f[i-2]%mod))%mod)%mod;
    }
}
void init3()
{
    ans[1]=ans[3]=ans[2]=ans[4]=0;
    ans[5]=5;
    ans[6]=16;
    for(int i=7; i<=maxn; i++)
    {
        ans[i]=((((((ans[i-1]%mod+ans[i-2]%mod)%mod+((1LL*(f[i-5]%mod)*1LL*(sum[i-1]%mod))%mod)%mod)%mod-(1LL*(f[i-4]%mod)*1LL*(sum[i-2]%mod)%mod)%mod)%mod+(((1LL*(f[i-2]%mod)*1LL*(f[i-4]%mod)%mod)%mod)%mod*1LL*f[i-5]%mod)%mod)%mod)+mod)%mod;
    }
}
int main()
{
    init();
    init2();
    init3();
    /*for(int i=0;i<=100;i++)
    {
        cout<<ans[i]<<" ";
        if(i%9==0)cout<<endl;
    }
    */
    scanf("%d",&t);
    int cas=0;
    while(t--)
    {
        scanf("%d",&n);
        printf("Case #%d: ",++cas);
        cout<<ans[n]<<endl;
    }
}


恩,这个题总体上思路没错,却死在了这个细节上。

这是尼玛何等卧槽!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值