首页 > 其他分享 >闲话 23.2.1

闲话 23.2.1

时间:2023-02-01 18:44:23浏览次数:58  
标签:int 闲话 ll st 23.2 times sum mod

闲话

symbolic method 写了 25k 了(
感觉能写很多的样子!

zAKy T4 代码最上面:
image

gap 大嘛?我不知道啊 gap 大不应该是 T2T3 出题人的事嘛

笑点集合?
其实没我啥事 但是 \(\land\) 出现时我笑了(
《正序开题》

出题报告?

这个题的出题思路是啥呢?我最开始有一道这个题,然后显然是个矩阵加速递推嘛。
然后我化出了一个第一行都是数,剩下只有 \((i, i - 1)\) 处有值的矩阵。当时还小,啥都不懂,然后就给同学们看。
没想到 crs 用一个全是 \(2^k\) 的三角矩阵给我切了,然后我急眼了。但是无可奈何啊!当时还小,啥都不懂。
当时就说 我一定要卡死你!这种感觉的

然后过了几个月,学了点多项式。知道常齐次线性递推咋做了。
突然就想到这题了。一看 这玩意可太吻合了!
我就用当时的笨法化简 化简出了下面的式子
就出了出来。
然后拿给他看嘛 他上来就用原来的法整个矩阵,然后发现矩阵 \(k\times k\) 的,乘一次就炸了
我顺利地卡死了他。

思维难度怎么样?
如果是巨佬下场了显然没问题 CF rating 3400+ 啊那可是(
但是我不知道这个做法是不是正常来说很难想
这题是按我的思维顺着出的 不好评价了

白的 Fibonacci

定义 \(F(k, n)\) 如下:

\[F(k,n) = \left \{ \begin{aligned} &st_0\ && k = 1\ \land\ n = 0 \\ &st_1\ && k = 1\ \land\ n = 1 \\ &0\ && k > 1 \ \land \ n < 0 \\ &a \times F(k, n - 1) + b \times F(k, n - 2)\ && k = 1 \ \land\ n > 1 \\ &t_k \times F(k, n - 1) + s^n \times F(k - 1, n)\ && \text{otherwise} \end{aligned} \right. \]

给定 \(F\) 递推式的各项系数和 \(k, n\),请你求出 \(F(k, n) \bmod 998244353\) 的值。

\(1 \leq k \leq 5 \times 10^3\),\(0 \leq n \le 2^{63}\),\(-998244352 \leq st_0, st_1, a, b, s, t_i \leq 998244352\)。

原来有个题目背景,挺长的就没放了。

我自己写的

“哥,这个,还记得吗?”

白手里摆弄着手机,无聊地说,屏幕上映出了一道题目

空刚想回话,白又点了一个链接,屏幕上映出了一串式子:

\(F_i = F_{i-1} + F_{i-2}\), 其中 \(F_1 = F_2 = 1\)。

\[A_{n} = \sum_{i=0}^{n} 2^i \ F_i\\ B_{n} = \sum_{i=0}^{n} 2^i \ A_i\\ C_{n} = \sum_{i=0}^{n} 2^i \ B_i\\D_{n} = \sum_{i=0}^{n} 2^i \ C_i \]

求 \(D_n \mod m\) 的值。

空显出了尴尬的神色。“这是那道……没加强完的搞笑题?”

“是,被切了。用了错误的方法。”白的样子有点不耐烦。

空突然灵光一现。他拿过手机,对妹妹说:“那我们不如把它抽象一下,别定义那么多数列了。就这样——”。

白看着空输入的表达式,开始了思考。“可以加强。”白突然说,看着空。空突然知道,妹妹究竟想到了什么。于是他写下了这个式子——

下面接题面。

然后是题解。

经过一些手膜,我们推断 \(F(k,n)\) 可以使用 \(k+1\) 阶常齐次线性递推表出。

\[F(k,n) = \sum_{i = 1}^{k+1} f_{k,i} \times F(k, n-i) \]

自然地,\(f_{1,1} = a, f_{1,2} = b\)。

现在讨论如何使用 \(f_{k-1}\) 推出 \(f_{k}\) 。以下讨论中 \(k > 1\)。

\[\begin{aligned} & F(k,n) = t_k \times F(k, n-1) + s^n \times F(k-1, n) \\ = \ & t_k \times F(k, n-1) + s^n \times \sum_{i = 1}^{k} f_{k-1,i} \times F(k-1, n-i) \qquad \text{(使用递推式表出)} \\ = \ & t_k \times F(k, n-1) + \sum_{i = 1}^{k} f_{k-1,i} \times s^{i} \times s^{n-i} \times F(k-1, n-i) \qquad (将s^n拆分,凑出系数) \\ = \ & t_k \times F(k, n-1) + \sum_{i = 1}^{k} f_{k-1,i} \times s^{i} \times (F(k, n-i) - t_k \times F(k, n - i - 1))\qquad (递推式移项带入) \\ = \ & t_k \times F(k, n-1) + \sum_{i = 1}^{k} f_{k-1,i} \times s^{i} \times F(k, n-i) - \sum_{i = 2}^{k+1} f_{k-1,i-1} \times s^{i-1} \times t_k \times F(k, n - i) \qquad (拆分和式) \\ = \ & \sum_{i=1}^{k+1} ( f_{k-1,i} \times s^i - f_{k-1,i-1} \times s^{i-1} \times t_k + t_k[i = 1] ) \times F(k, n-i) \qquad (表出系数) \end{aligned}\]

为方便,设 \(\forall k > 1,i > k+1, \ f_{k,0} = f_{k,i} = 0\)。于是 \(f_k\) 可以被 \(f_{k-1}\) 表为如下形式:

\[f_{k,i} = f_{k-1,i} \times s^i - f_{k-1,i-1} \times s^{i-1} \times t_k + t_k[i = 1] \]

因此我们可以 \(O(k^2)\) 地推出 \(F(k,n)\) 的递推系数与前 \(k+1\) 项值。随后 \(O(k \log k \log n)\) 地递推即可。

总时间复杂度 \(O(k ^ 2 + k \log k \log n)\)。

我自己写的
#include <bits/stdc++.h>
#define rep(i,a,b) for (register int(i) = (a); (i) <= (b); ++(i))
#define pre(i,a,b) for (register int(i) = (a); (i) >= (b); --(i))
using namespace std;
typedef unsigned long long ll;
const int N = 5000 + 10;
const int mod = 998244353, g = 3;
int k, st0, st1, a, b, s, ans;
int t[N], f[N], st[N];
ll n;

#ifdef ONLINE_JUDGE
    char buf[1<<21], *p1 = buf, *p2 = buf;  inline char getc() { return (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<21, stdin), p1 == p2) ? EOF : *p1++); }
    #define getchar getc
#endif
template <typename T> inline void get(T & x){
	x = 0; char ch = getchar(); bool f = false;
	while (ch < '0' or ch > '9') f = f or ch == '-',  ch = getchar();
	while (ch >= '0' and ch <= '9') x = (x<<1) + (x<<3) + (ch^48), ch = getchar(); f && (x = -x);
} template <typename T, typename ... Args> inline void get(T & x, Args & ... _Args) { get(x); get(_Args...); }

struct Light {
    int p, mx, sq, dsq[100], usq[100];
    void init(int _p, int _mx) {
        p = _p, mx = _mx; sq = sqrt(mx) + 1;
        dsq[0] = usq[0] = 1;
        rep(i,1,sq - 1) dsq[i] = 1ll * dsq[i-1] * p % mod;
        usq[1] = 1ll * dsq[sq - 1] * p % mod;
        rep(i,2,sq) usq[i] = 1ll * usq[i-1] * usq[1] % mod;
    } int qp(int k) {
        return 1ll * dsq[k % sq] * usq[k / sq] % mod;
    }
} pw;

int btrs[N << 5]; // butterfly_transform
inline int initrs(int k) {
    int limit = 1;
    while (limit < k) limit <<= 1;
    for (register int i = 0  ; i < limit; i ++) 
        btrs[i] = ((btrs[i >> 1] >> 1) | ((i & 1) ? limit >> 1 : 0));
    return limit;
}

inline ll qp(ll a, ll b) {
    ll ret = 1;
    while (b) {
        if (b & 1) ret = ret * a % mod;
        a = a * a % mod;
        b >>= 1;
    } return ret;
} inline ll inv(ll a) { return qp(a, mod-2); }

int L, w[2][1<<19];
inline int __INITILIZE__UNIT__ROOT__() {
    L = 1<<19;
    w[0][0] = w[1][0] = 1;
    int wn = qp(g, (mod-1) / L);
    for (register int i = 1; i < L; i++) w[0][L - i] = w[1][i] = 1ll * w[1][i - 1] * wn % mod;
    return 1;
} int __INITIALIZER__ = __INITILIZE__UNIT__ROOT__();

struct poly {
    vector <ll> f; 
    ll operator [] (const int & pos) const { return f[pos]; }
    ll & operator [] (const int & pos) { return f[pos]; }
    int deg() {return f.size(); }
    int deg() const  {return f.size(); }
    void Set(int n) { f.resize(n); }
    void Adjust() { while (f.size() > 1 and f.back() == 0) f.pop_back(); }
    void Reverse() { reverse(f.begin(), f.end()); }
    inline void NTT (const int lim, const int type) {
        Set(lim);
        for (register int i = 0; i < lim; i++) if (i < btrs[i]) swap(f[i], f[btrs[i]]);
        for (register int mid = 1; mid < lim; mid <<= 1) {
            for (register int i = L / (mid<<1), j = 0; j < lim; j += (mid << 1)) {
                for (register int k = 0; k < mid; k++) {
                    int x = f[j + k], y = w[type][i * k] * f[j + k + mid] % mod;
                    f[j + k] = (x + y) % mod;
                    f[j + k + mid] = (x - y + mod) % mod;
                }
            }
        } if (type == 1) return;
        ll inv = qp(lim, mod - 2);
        for (register int i = 0; i < lim; i++) f[i] = f[i] * inv % mod;
    } 
    friend poly operator - (const poly & x, const poly & y) {
        poly ret; ret.Set(max(x.deg(), y.deg()));
        for (register int i = 0; i < x.deg(); ++i) ret[i] = x[i];
        for (register int i = 0; i < y.deg(); ++i) ret[i] = (ret[i] - y[i] + mod) % mod;
        return ret;
    } void operator -= (const poly & x) {
        Set(max(deg(), x.deg()));
        for (register int i = 0; i < x.deg(); ++i) f[i] = (f[i] - x[i] + mod) % mod;
    } 
    friend poly operator * (const poly & x, const poly & y) {
        poly ret, A = x, B = y;
        int limit = initrs(A.deg() + B.deg() - 1);
        A.NTT(limit, 1), B.NTT(limit, 1); ret.Set(limit);
        for (register int i = 0; i < limit; i++) ret[i] = 1ll * A[i] * B[i] % mod;
        ret.NTT(limit, 0); ret.Adjust();
        return ret;
    } void operator *= (const poly & x) {
        poly A = x;
        int limit = initrs(deg() + A.deg() - 1);
        A.NTT(limit, 1); NTT(limit, 1);
        for (register int i = 0; i < limit; i++) f[i] = 1ll * A[i] * f[i] % mod;
        NTT(limit, 0); Adjust();
    }
    friend poly operator % (const poly & x, const poly & y) {
        poly A = x, B = y;
        A.Reverse(), B.Reverse(); B.Set(x.deg() - y.deg() + 1);
        B = B.Inv(); B *= A;
        B.Set(x.deg() - y.deg() + 1); B.Reverse();
        poly R = x - B * y; R.Set(y.deg() - 1);
        return R;
    }
    poly Inv() {
        poly ret; ret.Set(1);
        if (f.empty()) return ret;
        ret[0] = inv(f[0]); poly A, B;
        for (register int len = 2, limit; len < (deg() << 1); len <<= 1) {
            A.f.assign((*this).f.begin(), (*this).f.begin() + min(len, deg()));
            B = ret; B.Set(min(len, deg()));
            limit = initrs(A.deg() + B.deg() - 1);
            A.NTT(limit, 1); B.NTT(limit, 1);
            ret.Set(limit);
            for (register int i = 0; i < limit; i++) ret[i] = (2 - A[i] * B[i] % mod + mod) * B[i] % mod;
            ret.NTT(limit, 0);
            ret.Set(len);
        } ret.Set(deg()); return ret;
    }
} F, I;

inline void mul(poly & a, poly b, poly m) {
    a *= b;
    if (a.deg() >= m.deg()) a = a % m;
}

poly qp(poly a, ll b, poly m) {
    poly ret; ret.Set(1), ret[0] = 1;
    while (b) {
        if (b & 1) mul(ret, a, m);
        mul(a, a, m);
        b >>= 1;
    } return ret;
}

signed main() {
    get(k, n); 
    get(st[0], st[1], a, b, s);
    st[0] = (mod + st[0]) % mod; st[1] = (mod + st[1]) % mod; a = (mod + a) % mod; b = (mod + b) % mod; s = (mod + s) % mod;
    pw.init(s, k + 2);
    rep(i,2,k) get(t[i]), t[i] = (mod + t[i]) % mod;
    
    rep(i,2,k) st[i] = (1ll * a * st[i-1] + 1ll * b * st[i-2]) % mod; 
    rep(i,2,k) rep(j,1,k) 
        st[j] = (1ll * t[i] * st[j-1] + 1ll * pw.qp(j) * st[j]) % mod;
    if (n <= k) printf("%d\n", st[n]), exit(0);

    f[1] = a, f[2] = b;
    rep(i,2,k) pre(j,i+1,1) 
        f[j] = (1ll * pw.qp(j) * f[j] - 1ll * t[i] * pw.qp(j-1) % mod * f[j-1] % mod + (j == 1 ? t[i] : 0) + mod) % mod;

    F.Set(k+2); rep(i,1,k+1) F[k + 1 - i] = (mod - f[i]) % mod; 
    F[k+1] = 1;
    I.Set(2); I[0] = 0, I[1] = 1; 
    poly Ans = qp(I, n, F);
    rep(i,0,k) ans = (ans + 1ll * st[i] * Ans[i]) % mod;
    printf("%d\n", ans);
    return 0;
}

标签:int,闲话,ll,st,23.2,times,sum,mod
From: https://www.cnblogs.com/joke3579/p/chitchat230201.html

相关文章

  • 算法--2023.2.1
    1.力扣406--根据身高重建队列classSolution{//将二维数组按照不同人的身高升序排列,如果身高相同则按照位置降序排列publicint[][]reconstructQueue(int[][......
  • 闲话 23.1.31
    闲话symbolicmethod写了7k了(感觉能写很多的样子!有人膜我说我多项式全家桶就剩三道了我当机立断说这话显然fake我还特地核查了然后那人想挂我来着我就和他说:......
  • 闲话 23.1.29
    闲话感觉我现在得先提升自己的specify水平(这题我少说用了七八张草稿纸(只算写了主要过程的好题!loj:LightNovelOJ不要越级做题。——大师APJifengc今日推歌:1/6......
  • 闲话 23.1.28
    闲话引流昨日闲话以及有读者能给我讲讲最后的式子是咋化出来的吗?模拟赛51nod什么寄比赛(T1回文划分猜个结论,直接线性地前后每次删掉最短的border即可。感性理......
  • 闲话 23.1.27
    闲话今天下午可是被这题干沉默了(就磕这题了apj三点给我的题我到现在才看懂我发现我好像脑子真不行也没啥想说的了这题挺ex的(杂题ARC139F给定\(n,m\),\(A_i\)......
  • 闲话
    引子前几天水到了一个日本综艺,大概是“如果小朋友问你很深奥的问题,你会怎么回答?”。问的问题是这样的,“人生的意义是什么呢?”序章“人生的意义是什么呢?”确实是......
  • 【闲话】1.27 斐波那契数列一个性质及推广
    众所周知众所周知,斐波那契数列有一个性质:\[\gcd(f_{n},f_{m})=f_{\gcd(n,m)}\]在证明他之前,先来看个引理:\(\text{Lemma}\1\)\[f_{n+m}=f_{n}\timesf_{m-1}+f_{n+1......
  • 闲话 23.1.26
    闲话下午补。今日模拟赛T3小恶心。原题似乎是pe444,但是好像不让写题解的样子?反正不是原题啦,随便!首先观察\(E(111)=5.2912\)这个数值就很不对劲。扔进计算器发现......
  • 闲话 23.1.25
    杂题[集训队作业2019]青春猪头少年不会梦到兔女郎学姐若干个正整数排成一个序列,其中数字\(i\)的出现次数为\(r_i\),对于每一个这样的序列,定义他的权值如下:把这个序......
  • 闲话 23.1.24
    闲话不知道该写啥了欸~那就随便写写吧!祝贺jjdw参与的洛谷大月赛成功举办!补题链接指导:jijidawang今日推歌:Aster-春卷饭feat.初音未来闲话今天做题时看到这么......