杂题
2025-11-04

这么爱计数


A. 图 / HDU4903 The only survival

https://vjudge.net/problem/HDU-4903#author=DeepSeek_zh

  • 很容易想到基于按 dis 从小到大枚举的做法

    但是发现算方案就必须要知道每个点的具体 dis,就导致难以 DP,只能搜索,这样复杂度就不太好看。

  • 一个显然的观察:并不关心 \(1,n\) 以外点的标号,所以可以把 \(O(n^k)\) 的暴搜优化到 \(O(\binom{n+k}k\cdot (n+k))\),然后做多重集排列即可。

    模数非质时的多重集排列:link

#include <bits/stdc++.h>
int main() {
#ifdef ONLINE_JUDGE
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    std::freopen("graph.in", "r", stdin);
    std::freopen("graph.out", "w", stdout);
#else
    std::freopen(".in", "r", stdin);
    std::freopen(".out", "w", stdout);
    const auto stime = std::chrono::steady_clock::now();
#endif
    int n, k, L, mod;
    std::cin >> n >> k >> L >> mod;
    if (L < k) {
        std::cout << 0 << '\n';
        return 0;
    }
    std::vector<std::vector<long long> > C(n + 1, std::vector<long long> (n + 1));
    C[0][0] = 1ll;
    for (int i = 1; i <= n; ++i) {
        C[i][0] = 1ll;
        for (int j = 1; j <= i; ++j)
            C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
    }
    std::vector<int> dis(n + 1), s;
    int res = 0;
    std::function<void(int, int, long long)> DFS = [&](int x, int d, long long now) {
        if (x == n) {
            auto s0 = now, s1 = now;
            for (int i = 1; i < n; ++i)
                if (dis[i] >= k)
                    (s0 *= L) %= mod, (s1 *= L) %= mod;
                else if (L - (k - dis[i] - 1)) {
                    (s0 *= L - (k - dis[i] - 1)) %= mod;
                    (s1 *= L - (k - dis[i] - 1) - 1) %= mod;
                }
                else {
                    s0 = s1 = 0ll;
                    break;
                }
            dis[x] = k;
            auto u = 1ll;
            int cnt = n - 2;
            for (auto i : s)
                (u *= C[cnt][i]) %= mod, cnt -= i;
            (res += u * (s0 + mod - s1) % mod) %= mod;
            return;
        }
        for (int i = d; i <= k + 1; ++i) {
            auto s0 = now, s1 = now;
            for (int j = 1; j < x; ++j)
                if (dis[j] >= i)
                    (s0 *= L) %= mod, (s1 *= L) %= mod;
                else if (L - (i - dis[j] - 1)) {
                    (s0 *= L - (i - dis[j] - 1)) %= mod;
                    (s1 *= L - (i - dis[j] - 1) - 1) %= mod;
                }
                else {
                    s0 = s1 = 0ll;
                    break;
                }
            dis[x] = i;
            if (dis[x] != dis[x - 1])
                s.push_back(1);
            else
                ++s.back();
            if (i == k + 1)
                s1 = 0ll;
            DFS(x + 1, i, (s0 + mod - s1) % mod);
            if (dis[x] != dis[x - 1])
                s.pop_back();
            else
                --s.back();
        }
        return;
    };
    DFS(2, 1, 1);
    std::cout << res % mod << '\n';
#ifndef ONLINE_JUDGE
    std::cerr << std::fixed << std::setprecision(6) << std::chrono::duration<double> (std::chrono::steady_clock::now() - stime).count() << "s\n";
#endif
    return 0;
}

B. 路线 / ARC136E Non-coprime DAG

https://www.luogu.com.cn/problem/AT_arc136_e

  • 做过 CF870F Paths 可以很快反应过来:\(x\)\(y\) 是否可以同时被选,取决于它们各自的最小质因子是否能在 \(x,y\) 之间交汇(或用 \(2\) 作跳板)。

    接着就发现由于 \(2\) 间隔出现,此时再分奇偶性就会显得非常合理。

  • 两个偶数总是不能同时被选;对于奇数 \(x\) 和偶数 \(y\),要求 \(y\in [x-f(x)+1,x+f(x)-1]\)

  • 考察奇数的选取。容易发现,钦定用 \(2\) 作跳板,则两个奇数 \(x,y(x<y)\) 能同时被选,当且仅当:

    • \(f(i)\)\(i\) 的最小质因子,则 \(x+f(x)> y-f(y)\)

    发现实际上可以认为 \(x\) 代表区间 \([x-f(x),x+f(x)-1]\)。那么两个点可以同时被选当且仅当它们代表的区间有交(这样就去掉了 \(x,y\) 之间的偏序条件)

    这样发现对『代表区间』的定义,在奇数视角和偶数视角下是冲突的,可以发现偶数视角的区间更紧;事实上,应该采用 \([x-f(x)+1,x+f(x)-1]\) 这个看似充分不必要的定义,因为端点总是奇数,导致 \(x+f(x)> y-f(y)\)\(x+f(x)-1<y-f(y)+1\) 不能同时成立。

  • 进一步推广结论,容易发现多个奇数可以同时被选,当且仅当它们代表的区间有交。故可以枚举值域中的点,找加权覆盖次数最大值。

#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef ONLINE_JUDGE
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
#else
    std::freopen(".in", "r", stdin);
    std::freopen(".out", "w", stdout);
    const auto stime = std::chrono::steady_clock::now();
#endif
    int n;
    std::cin >> n;
    std::vector<int> fac(n + 1), l(n + 1), r(n + 1);
    for (int i = 2; i <= n; ++i) {
        if (!fac[i]) {
            fac[i] = i;
            for (int j = 2 * i; j <= n; j += i)
                if (!fac[j])
                   fac[j] = i;
        }
        l[i] = std::max(1, i - fac[i] + 1);
        r[i] = std::min(i + fac[i] - 1, n);
    }
    std::vector<int> a(n + 1);
    std::vector<long long> dif(n + 1);
    for (int i = 1; i <= n; ++i) {
        std::cin >> a[i];
        if (i == 1 || i % 2 == 0)
            continue;
        dif[l[i]] += a[i];
        if (r[i] != n)
            dif[r[i] + 1] -= a[i];
    }
    auto res = 0ll;
    std::partial_sum(dif.begin(), dif.end(), dif.begin());
    for (int i = 1; i <= n; ++i) {
        auto now = a[1] + dif[i];
        if (i % 2 == 0)
            now += a[i];
        res = std::max(res, now);
    }
    std::cout << res << '\n';
#ifndef ONLINE_JUDGE
    std::cerr << std::fixed << std::setprecision(6) << std::chrono::duration<double> (std::chrono::steady_clock::now() - stime).count() << "s\n";
#endif
    return 0;
}

A. 列车扫除

https://www.becoder.com.cn/contest/6708/problem/1

绝对聪明的 A, B, C 在一起玩 Nim,有三堆石子 \(c_{1,2,3}\),每次可以任选一堆拿走正整数个,不能拿的人扣一分,他的上一个人加一分。

给定 \(q\) 次询问,形如:

  • 现在知道 \(\forall \, i=1,2,3,c_i\in[l_i,r_i]\)。对于这 \(\prod_{i=1,2,3}r_i-l_i+1\) 种可能的情况,对于每个人,求出分数之和。

\(q\le 10^6,V=10^9\)

  • 容易发现,胜,平,负三个状态会被分给三个人,且一共只有三种分配方式。

  • 当只剩一堆石头时,操作者胜;石头状态为 \((0,1,1)\) 时,操作者负。


B. 换来换去

https://www.becoder.com.cn/contest/6708/problem/2

\(n\) 个有标号的球任意分成任意组,组是无顺序的,且要求每组球个数 \(\ge 2\),求方案数,对质数取模。

\(n\le 10^7\)

  • 发现这是一个类斯特林数的问题,二项式反演得到答案式为:

    \[ \sum_{i=0}^n (-1)^{n-i}\binom ni \sum_{j=0}^i \begin{Bmatrix} i\\ j\end{Bmatrix} \]

    用斯特林数通项展开:

    \[ \sum_{i=0}^n (-1)^{n-i}\binom ni \sum_{j=0}^i \sum_{k=0}^j(-1)^{j-k}\dfrac {k^i}{(j-k)!\cdot k!} \]

    很容易注意到一个二项式定理的结构,故交换求和顺序:

    \[ \sum_{j=0}^n \sum_{k=0}^j \dfrac {(-1)^{j-k}}{(j-k)!\cdot k!}\cdot \sum_{i=j}^n \binom ni (-1)^{n-i}k^i \]

    发现一个很严重的问题在于 \(i\) 的起始范围是 \(j\) 而不是 \(0\),但如果我们把一开始的式子改写成这样:

    \[ \sum_{i=0}^n (-1)^{n-i}\binom ni \sum_{j=0}^n \begin{Bmatrix} i\\ j\end{Bmatrix} \]

    容易发现当 \(j>i\)\(\begin{Bmatrix} i\\ j\end{Bmatrix}=0\),和原式的值相同,且斯特林数通项对于 \(j>i\) 也是成立的,故原式等价于

    \[ \begin{aligned} &\sum_{j=0}^n \sum_{k=0}^j \dfrac {(-1)^{j-k}}{(j-k)!\cdot k!}\cdot \sum_{i=0}^n \binom ni (-1)^{n-i}k^i\\ =&\sum_{j=0}^n \sum_{k=0}^j \dfrac {(-1)^{j-k}}{(j-k)!\cdot k!}\cdot (k-1)^n\\ =&\sum_{k=0}^n \dfrac {(k-1)^n}{k!}\cdot \sum_{j=0}^{n-k} \dfrac {(-1)^j}{j!}\\ \end{aligned} \]

    后者内部与 \(k\) 无关,是可前缀和计算的,只需要考虑在 \(O(1)\) 内求出 \((k-1)^n\) 的值,筛一下,对于质数(约 \(\dfrac n{\ln n}\) 个)快速幂,合数用积性函数之类即可。

#include <bits/stdc++.h>
int main() {
#ifdef ONLINE_JUDGE
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    std::freopen("card.in", "r", stdin);
    std::freopen("card.out", "w", stdout);
#else
    std::freopen(".in", "r", stdin);
    std::freopen(".out", "w", stdout);
    const auto stime = std::chrono::steady_clock::now();
#endif
    int T;
    for (std::cin >> T; T--; ) {
        int n, mod;
        std::cin >> n >> mod;
        std::vector<int> tag(n + 1), p, pw(n + 1);
        auto qkp = [&](long long x, int y) {
            auto res = 1ll;
            for (; y; (x *= x) %= mod, y >>= 1)
                if (y & 1)
                    (res *= x) %= mod;
            return res;
        };
        pw[1] = 1ll;
        for (int i = 2; i <= n; ++i) {
            if (!tag[i]) {
                pw[i] = qkp(i, n);
                p.push_back(i);
            }
            for (auto j : p) {
                if (i > n / j)
                    break;
                tag[i * j] = 1;
                pw[i * j] = (long long)pw[i] * pw[j] % mod;
                if (i % j == 0)
                    break;
            }
        }
        std::vector<int> inv(n + 1), s(n + 1);
        inv[0] = 1ll;
        for (int j = 1; j <= n; ++j)
            inv[j] = (long long)inv[j - 1] * j % mod;
        inv[n] = qkp(inv[n], mod - 2);
        for (int j = n - 1; j; --j)
            inv[j] = (long long)inv[j + 1] * (j + 1) % mod;
        s[0] = inv[0];
        for (int j = 1; j <= n; ++j) {
            if (j & 1)
                s[j] = s[j - 1] + mod - inv[j];
            else
                s[j] = s[j - 1] + inv[j];
            if (s[j] >= mod)
                s[j] -= mod;
        }
        auto res = (long long)s[n] * ((n & 1) ? mod - 1 : 1);
        for (int k = 1; k <= n; ++k)
            res += (long long)pw[k - 1] * inv[k] % mod * s[n - k] % mod;
        std::cout << res % mod << '\n';
    }
#ifndef ONLINE_JUDGE
    std::cerr << std::fixed << std::setprecision(6) << std::chrono::duration<double> (std::chrono::steady_clock::now() - stime).count() << "s\n";
#endif
    return 0;
}

C. 画家

https://www.becoder.com.cn/contest/6714/problem/3

  • ARC 特供删十字,故时光倒流,转化成在图上删相同颜色的十字 / 行 / 列。

  • \(f_{i,j}\) 表示合法的 \(i\)\(j\) 列地图。发现同颜色的删行 + 删列会和直接删十字算重,


B. 灯光秀 / CF1545C AquaMoon and Permutations

https://www.luogu.com.cn/problem/CF1545C

  • 第一步需要想到,如果某一列的某个数,只有一个排列有,那么这个排列必须被选入拉丁方;

    用这个必选的排列,可以排除掉一些与之冲突、不能选入拉丁方的排列。


A. bot 的能量堆

https://www.becoder.com.cn/contest/6731/problem/1

超越一切震慑凡人

给定正整数 \(x,y\),你可以执行下面三种操作:

  1. \(x,y\) 同时加 1;
  2. \(x,y\) 同时减一;
  3. 对于 \(\gcd(x,y)\) 的一个质因子 \(p\),将 \(x,y\) 同时除以 \(p\)

问最少花费多少次操作使得 \(\min(x,y)=1\)。多测。

\(T\le 300,1\le x,y\le 10^9\)

  • 不妨先考虑 \(x\ne y\) 的情况,发现三种操作都不会使 \(x,y\) 的相对大小关系改变。故令 \(x<y\),考虑让 \(x\) 变为 1。

  • \(d=y-x\), 很容易注意到 \(d\) 的值不会在前两种操作中改变,由辗转相减,\(\gcd(x,y)=\gcd(d, x)\),即操作三每次选取的 \(p\) 总是 \(d\) 的质因子,且总能通过若干次操作 1/2 让 \(p\) 能够执行。

    每次执行操作 3 后,\(d\gets d\div p\),每次只需让 \(x\) 变为 \(\lfloor \frac xp\rfloor\)\(\lceil \frac xp\rceil\)

    直接记搜的话,容易发现状态总数是 V 因数总数。

  • 对于 \(x=y\) 的情况,答案至多为 \(x\) 的质因子数量。暴搜 + 剪枝非常可过。

    有一种神秘的处理方式…

    if (x == y) {
        auto calc = [&](int x) {
            int cnt = 0;
            for (int i = 2; i * i <= x; ++i)
                for (; x % i == 0; ++cnt, x /= i);
            return cnt + (x != 1);
        };
        int to = calc(x), res = to;
        for (int i = std::max(x - to, 1); i <= x + to; ++i)
            res = std::min(res, calc(i) + std::abs(i - x));
        std::cout << x << '\n';
        continue;
    }

    容易发现这东西没什么道理,反例大概率存在但在小范围内确实难以构造。总之数据没卡到。


B. bot 的矩阵

https://www.becoder.com.cn/contest/6731/problem/2

有一个 \(n\times n\) 的二维数组,初始只知道 \(m\) 个位置的数 \(a_{x,y}\),以及每行、每列的元素和 \(sx_{1\cdots n},sy_{1\cdots n}\)

构造出一个合法的解,每个数在 \([-2^63,2^63)\) 内。

\(n\le 2000\),\(a_{x,y},sx_i,sy_i\in [-10^9,10^9]\)\(m\le n^2\)

  • 听说很容易想到二分图,但实在反应不过来。但在乱填的时候发现,如果出现了『必填』的情况,是一个行列交错的链式反应,这样就很容易想到二分图了

    原理是同时影响行 \(i\)\(j\) 的元素只有 \((i, j)\)

  • 相当于给一个 \(2n\) 个点 \(n^2\) 条边的二分图,其中一些边权是已知的,那么不妨认为这些边被删除了

    同时也是一个 \(n^2\) 个元,\(2n-1\) 个方程的方程组(\(sx=sy\) 会消掉一条方程);故很多元其实可以直接赋 \(0\),只拿 \(2n-1\) 个元出来解方程。

  • 在挖掉已知边的二分图上任意找生成树(森林)就可以满足 \(2n-1\) 的限制,结合树上高斯消元,从叶子开始解方程即可。

#include <bits/stdc++.h>
#define int long long
#define nec getchar
void read(int &x) {
    x = 0;
    char ch = nec();
    bool flag = false;
    for (; ch < '0' || ch > '9'; ch = nec())
        if (ch == '-')
            flag = true;
    for (; ch >= '0' && ch <= '9'; ch = nec())
        x = x * 10 + ch - '0';
    if (flag)
        x = -x;
    return;
}
signed main() {
#ifdef ONLINE_JUDGE
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
#else
    std::freopen("matrix3.in", "r", stdin);
    std::freopen(".out", "w", stdout);
    const auto stime = std::chrono::steady_clock::now();
#endif
    int T;
    for (read(T); T--; ) {
        int n, m;
        read(n), read(m);
        std::vector<int> sx(n + 1), sy(n + 1);
        for (int i = 1; i <= n; ++i)
            read(sx[i]);
        for (int i = 1; i <= n; ++i)
            read(sy[i]);
        std::vector<std::vector<int> > vis(n + 1, std::vector<int> (n + 1));
        std::vector<std::vector<long long> > a(n + 1, std::vector<long long> (n + 1));
        std::vector<int> tx(n + 1), ty(n + 1);
        auto work = [&](int i, int j, int c) {
            vis[i][j] = 1;
            ++tx[i], ++ty[j];
            sx[i] -= c, sy[j] -= c, a[i][j] = c;
            return;
        };
        for (int x, y, c; m--; ) {
            read(x), read(y), read(c);
            work(x, y, c);
        }
        if (std::accumulate(sx.begin() + 1, sx.end(), 0ll) != std::accumulate(sy.begin() + 1, sy.end(), 0ll)) {
            std::cout << "NoSolution!" << '\n';
            continue;
        }
        std::vector<int> fx(n + 1), fy(n + 1);
        std::function<bool(void)> check = [&](void) {
            for (int x = 1; x <= n; ++x)
                if (!fx[x]) {
                    if (tx[x] == n) {
                        if (sx[x] != 0)
                            return false;
                        fx[x] = 1;
                        if (!check())
                            return false;
                    }
                    else if (tx[x] == n - 1) {
                        for (int y = 1; y <= n; ++y)
                            if (!vis[x][y]) {
                                work(x, y, sx[x]);
                                fx[x] = 1;
                                if (!check())
                                    return false;
                            }
                    }
                }
            for (int y = 1; y <= n; ++y)
                if (!fy[y]) {
                    if (ty[y] == n) {
                        if (sy[y] != 0)
                            return false;
                        fy[y] = 1;
                        if (!check())
                            return false;
                    }
                    else if (ty[y] == n - 1) {
                        for (int x = 1; x <= n; ++x)
                            if (!vis[x][y]) {
                                work(x, y, sy[y]);
                                fy[y] = 1;
                                if (!check())
                                    return false;
                            }
                    }
                }
            return true;
        };
        if (!check()) {
            std::cout << "NoSolution!" << '\n';
            continue;
        }
        std::function<void(int, int)> DFS = [&](int x, int op) {
            if (op == 0) {
                fx[x] = 1;
                for (int i = 1; i <= n; ++i)
                    if (!vis[x][i] && !fy[i]) {
                        DFS(i, 1);
                        work(x, i, sy[i]);
                    }
            }
            else {
                fy[x] = 1;
                for (int i = 1; i <= n; ++i)
                    if (!vis[i][x] && !fx[i]) {
                        DFS(i, 0);
                        work(i, x, sx[i]);
                    }
            }
            return;
        };
        for (int i = 1; i <= n; ++i)
            if (!fx[i])
                DFS(i, 0);
        for (int i = 1; i <= n; ++i)
            if (!fy[i])
                DFS(i, 1);
        std::cout << "Botany!" << '\n';
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j)
                std::cout << a[i][j] << ' ';
            std::cout << '\n';
        }
    }
#ifndef ONLINE_JUDGE
    std::cerr << std::fixed << std::setprecision(6) << std::chrono::duration<double> (std::chrono::steady_clock::now() - stime).count() << "s\n";
#endif
    return 0;
}

A. 数码串

https://www.becoder.com.cn/contest/6736/problem/1

给定一个长度为 \(n\) 的数字串,现在需要给它分为若干段,问在所有 \(2^{n-1}\) 种分段方式中,有多少种满足:

  • 在任意相邻的两段中,有至少一段,其对应的十进制数是 \(D\) 的倍数。

答案对 \(10^9+7\) 取模。

多测,\(n\le 2\times 10^5,D\le 10^6,T\le 100\)

部分分特殊性质\(\gcd(D,10)=1\)

  • 发现若 \(a_{l\cdots r}\)\(D\) 的倍数,记 \(s_i=s_{i+1}+a_i\times 10^{n-i}\),那么 \(\dfrac{s_l-s_{r+1}}{10^{n-r}}\bmod D=0\)

    题目要求,这个转移点和上个转移点,至少有一个满足该式。显然可以类 DP 地做。

  • 对于 \(D\)\(10\) 互质的情况,原条件等价于 \(s_l\equiv s_{r+1}\pmod D\),用一个桶记录 DP 值即可

  • \(D=2^*\times 5^?\times m\),发现 \(m\)\(10\) 互质,或许可以套用上方的做法

    由于 \(D\le 10^6 < 2^{20}\),对于一个固定的 \(r\),所有 \(l\le r-20\) 项的 \(a_l\)\(a_{l\cdots r}\bmod (2^*\times 5^?)\) 的贡献总是 \(0\),故在只考虑 \(2^*\times 5^?\) 时, \(l\le r-20\) 的可选性和 \(l=r-20\) 的可选性相同。只需要对于 \(\bmod m\) 沿用桶做法即可。

    对于 \(l\ge r-20\),暴力即可,复杂度 \(O(T(n+D))\)

注意 \(s_l-s_{r+1}\) 里的 \(r+1\),调成鸲了

#include <bits/stdc++.h>
const int mod = 1e9 + 7;
int main() {
#ifdef ONLINE_JUDGE
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    std::freopen("digit.in", "r", stdin);
    std::freopen("digit.out", "w", stdout);
#else
    std::freopen("./test/20251113/digit/ex_digit1.in", "r", stdin);
    std::freopen(".out", "w", stdout);
    const auto stime = std::chrono::steady_clock::now();
#endif
    int T;
    std::vector<std::array<long long, 2> > c(1e6);
    for (std::cin >> T; T--; ) {
        std::string a;
        int d, n, m, p;
        std::cin >> a >> d, n = (int)a.length();
        a = "#" + a;
        std::vector<std::vector<long long> > f(n + 1, std::vector<long long> (2));
        f[0][0] = 1ll;
        m = d;
        for (; m % 2 == 0; m /= 2);
        for (; m % 5 == 0; m /= 5);
        p = d / m;
        for (int i = 0; i < m; ++i)
            c[i][0] = c[i][1] = 0ll;
        std::vector<int> s(n + 2);
        for (int i = n, k = 1; i; --i, (k *= 10) %= m)
            s[i] = (s[i + 1] + (a[i] - '0') * k) % m;
        auto s0 = 0ll;
        for (int i = 1; i <= n; ++i) {
            int now = 0;
            for (int j = i, k = 1; j > i - 20 && j; --j, (k *= 10) %= d) {
                (now += (a[j] - '0') * k) %= d;
                if (now == 0)
                    (f[i][0] += f[j - 1][0] + f[j - 1][1]) %= mod;
                else
                    (f[i][1] += f[j - 1][0]) %= mod;
            }
            if (i > 20) {
                (c[s[i - 20]][0] += f[i - 21][0]) %= mod;
                (c[s[i - 20]][1] += f[i - 21][1]) %= mod;
                (s0 += f[i - 21][0]) %= mod;
                int now = 0;
                for (int j = i, k = 1; j >= i - 20; --j, (k *= 10) %= p)
                    (now += (a[j] - '0') * k) %= p;
                if (now == 0) {
                    (f[i][0] += c[s[i + 1]][0] + c[s[i + 1]][1]) %= mod;
                    (f[i][1] += s0 + mod - c[s[i + 1]][0]) %= mod;
                }
                else
                    (f[i][1] += s0) %= mod;
            }
        }
        std::cout << (f[n][0] + f[n][1]) % mod << '\n';
    }
#ifndef ONLINE_JUDGE
    std::cerr << std::fixed << std::setprecision(6) << std::chrono::duration<double> (std::chrono::steady_clock::now() - stime).count() << "s\n";
#endif
    return 0;
}

B. 背包

https://www.becoder.com.cn/contest/6736/problem/2


言论