题解 [牛客IOI周赛17-提高组 B] 卷积

卷积

https://ac.nowcoder.com/acm/contest/5857/B

题目描述

给定序列 的递推公式

为序列 的生成函数,求 的第 项对 取模。

正解

最终答案 是一个等比数列求和的形式,等价于

现在直接多项式求逆就可以做到 了,感觉卡卡就能过

比赛的时候不会生成函数真的自闭了啊,然后想起了 rqy 博客里求通项 / 递推公式的方法,尝试自己推了一下。

先对 求出其封闭形式,然后如果 也能表示成一个类似于生成函数封闭形式的玩意,就能求出 的递推式。

先对 求其封闭形式。

然后求

发现 的封闭形式类似,应该可以求出其递推公式。

那么很显然数列 的递推公式是 ,特别的:有

直接递推可以做到 ,或者用矩阵优化到

代码

#include <bits/stdc++.h>

using namespace std;

const int mod = 998244353;

int n, a, b;

struct matrix {
    long long c[2][2];
    inline matrix () { c[0][0] = c[0][1] = c[1][0] = c[1][1] = 0; }
} ;

matrix mul(const matrix &A, const matrix &B) {
    matrix C;
    for(int i = 0; i < 2; ++i)
        for(int j = 0; j < 2; ++j)
            for(int k = 0; k < 2; ++k)
                C.c[i][j] += A.c[i][k] * B.c[k][j];
    C.c[0][0] %= mod;
    C.c[0][1] %= mod;
    C.c[1][0] %= mod;
    C.c[1][1] %= mod;
    return C;
}

int main() {
    scanf("%d %d %d", &n, &a, &b);
    /* g_n = (a + 1) * g_{n - 1} + b * g_{n - 2} */
    matrix base, res;
    res.c[0][0] = res.c[1][1] = 1;
    base.c[0][0] = (a + 1) % mod;
    base.c[1][0] = b;
    base.c[0][1] = 1;
    base.c[1][1] = 0;
    while(n) {
        if(n & 1) res = mul(res, base);
        base = mul(base, base), n >>= 1;
    }
    printf("%lld\n", res.c[0][1]);
    return 0;
}
全部评论
还是直接 BM 板子吧 233
点赞 回复 分享
发布于 2020-06-07 09:45
orz
点赞 回复 分享
发布于 2020-06-06 22:07

相关推荐

不愿透露姓名的神秘牛友
07-01 17:13
想去,但是听说加班强度实在难崩,所以拒绝了,现在有点心梗对面hr感觉也是实习生,打电话的时候怪紧张的,但是感觉人很好嘞
水中水之下水道的鼠鼠:哥们这不先去体验一下,不行再跑呗,大不了混个实习经历(有更好的转正offer就当我没说)
点赞 评论 收藏
分享
06-08 22:25
门头沟学院 Java
从零开始的转码生活:这hr不会打开手机不分青红皂白给所有人群发这句话,过一会再给所有人再发一遍,这肯定会有重复的,不管,再过一会再发一遍
点赞 评论 收藏
分享
评论
6
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务