每日一题

10.2

D. Magic Gems

题目大意(自己总结
给你n个空间,可以放魔法石头,也可以放普通石头,可以将一个魔法石变成M个普通石头,需要M个空间可以有多少种不同的宝石组合,从而使所占用的空间总数为 N 个单位?打印答案,模数为 1000000007 ( 109+7 )。如果雷兹巴所需的魔法宝石数量不同,或者雷兹巴需要分割的宝石的指数不同,那么这两种配置就会被认为是不同的。
输入包含一行由 2 和 M 组成的整数 N 和 M ( 1≤N≤1018 , 2≤M≤100 )。
题目主要实现思路
首先考虑第一个空间,可以考虑到转移方程dp【i] =dp [ i -1 ],
如果i>=m,可以加上将这m个空间成普通宝石得数量也就是dp[ i ] +=dp[i - m] ;由于n够大,用矩阵快速幂加速递推

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e6 + 10;

const int mod = 1e9 + 7;

using martrix = vector<vector<int>>;

martrix mul(martrix &a, martrix &b)

{

    int n = a.size();

    int m = b[0].size();

    martrix c = martrix(n, vector<int>(m, 0));

    for (int i = 0; i < n; i++)

    {

        for (int j = 0; j < a[i].size(); j++)

        {

            for (int k = 0; k < m; k++)

            {

                c[i][k] = (a[i][j] * b[j][k] + c[i][k]) % mod;

            }

        }

    }

    return c;

}

martrix m_pow(martrix a, int b, martrix &f0)

{

    martrix res = f0;

    while (b)

    {

        if (b & 1)

        {

            res = mul(a, res);

        }

        b >>= 1;

        a = mul(a, a);

    }

    return res;

}

void solve()

{

    int n, m;

    cin >> n >> m;

    vector<vector<int>> f0(m, vector<int>(1, 0));

    f0[m - 1][0] = 1;

    martrix A(m, vector<int>(m, 0));

    for (int i = 0; i < m - 1; i++)

    {

        A[i][i + 1] = 1;

    }

    A[m - 1][0] = 1;

    A[m - 1][m - 1] = 1;

    auto res = m_pow(A, n, f0);

    cout << res[m - 1][0] << '\n';

}

signed main()

{

    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

    int T;

    T = 1;

    // cin >> T;

    while (T--)

        solve();

    return 0;

}

https://codeforces.com/problemset/problem/1982/C
题目大意(自己总结示 T 组数据。所有数据的 n 之和 ≤2e5。
每组数据输入 n(1≤n≤1e5) L R(1≤L≤R≤1e9) 和长为 n 的数组 a(1≤a[i]≤1e9)。
每次操作,删除 a 的一个非空前缀。
如果该次操作删除的元素之和在闭区间 [L,R] 中,那么得到一分,否则不得分。
操作直到 a 为空。
输出最大总得分。
题目主要实现思路
滑动窗口维护窗口内的值在这个区间即可,注意维护出队是满足知道$nw<=ar$ 即可,
而不是要满足出队$nw \leq ar , nw \geq al$ 这样又可能一次出队直接使得$nw \leq al$ 从而一直出队造成错误

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e6 + 10;

const int mod = 998244353;

void solve()

{

    int n, al, ar;

    cin >> n >> al >> ar;

    vector<int> a(n);

    for (int i = 0; i < n; i++)

    {

        cin >> a[i];

    }

    int nw = 0, ans = 0;

    int l = 0;

    for (int r = 0; r < n; r++)

    {

        nw += a[r];

        if (nw >= al && nw <= ar)

        {

            ans++;

            l = r + 1;

            nw = 0;

        }

        else if (nw > ar)

        {

            while (l < r && nw > ar)//注意这个地方

            {

                nw -= a[l];

                l++;

            }

            if (nw >= al && nw <= ar)

            {

                ans++;

                l = r + 1;

                nw = 0;

            }

        }

    }

    cout << ans << '\n';

}

signed main()

{

    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

    int T;

    T = 1;

    cin >> T;

    while (T--)

        solve();

    return 0;

}
posted @ 2025-10-03 16:36  Jwe1  阅读(13)  评论(0)    收藏  举报