每日一题
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;
}

浙公网安备 33010602011771号