消息传播{递推+高精压位}

  • 【题目描述】
    众所周知,HYF有很多小姊妹。 HYF每天放学之后都要跟(不同的)MM约会。HYF这天约会的时候不巧被jzt撞上了……虽然换一个新的MM约会这种事情对于HYF来说如同家常便饭,所谓“好事不出门,坏事传千里”,jzt迅速将这个消息传播开来。 每个听到这个消息的人首先会震惊一段时间(他怎么又换MM了- -~!),但是这样的震惊只会持续2个时刻(因为这对于HYF来说太正常了= =~!)。如果他在第i个时刻听到这个消息,就会从第(i+2)个时刻开始传播这个消息,每个时刻把这个消息告诉两个人,当然他只会告诉不知道这个消息的人。但是当他连续告诉了10个人之后,他就会口干舌燥,停止传播。 jzt在第0时刻撞到HYF(当然jzt也有震惊时间),请问第N时刻共有多少人知道了这个消息?

  • 【Sample Input】(一行一个整数N,表示第N时刻)
    【输入样例1】4
    【输入样例2】1
    【输入样例3】10

  • 【Sample Output】(一行一个整数,表示N分钟后知道这个消息的总人数)
    【输出样例1】11
    【输出样例2】1
    【输出样例3】651

  • 【数据规模】
    20%的数据,N<=20
    60%的数据,N<=1000
    100%的数据,N<=10000


【题解】递推+高精压位
递推应该是比较好想的,f[i]=(f[i-2]+f[i-3]+…+f[i-6])*2,当然想要再进一步合并也可。
高精的话注意极限情况的位数就好了。大概2000+位吧。


#include <cstdio>
#include <iostream>
#define bit 1000000
#define LL long long
struct num{ LL l,a[500];};
int n;num ans,a[10005];
    num operator +(num x,num y)
    {
        x.l=std::max(x.l,y.l);
        for (int i=1;i<=x.l;++i) x.a[i]+=y.a[i];
        for (int i=1;i<=x.l;++i)
            x.a[i+1]+=x.a[i]/bit,x.a[i]%=bit;
        if (x.a[x.l+1]) ++x.l;
        return x;
    }
    num operator *(num x,int y)
    {
        for (int i=1;i<=x.l;++i) x.a[i]*=y;
        for (int i=1;i<=x.l;++i)
            x.a[i+1]+=x.a[i]/bit,x.a[i]%=bit;
        if (x.a[x.l+1]) ++x.l;
        return x;
    }
    void print(num x)
    {
        printf("%d",x.a[x.l]);
        for (int i=x.l-1;i;--i) printf("%.6d",x.a[i]);
    }
int main()
{
    scanf("%d\n",&n);
    a[0].a[1]=a[0].l=1;
    for (int i=1;i<=n;++i)
        for (int j=std::max(0,i-6);j<=i-2;++j) a[i]=a[i]+a[j]*2;
    for (int i=0;i<=n;++i) ans=ans+a[i];
    print(ans);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值