日常刷题2025-2-21

日常刷题2025-2-21

C. Beautiful Sequence子序列计数问题

https://codeforces.com/contest/2069/problem/C

思路:线性DP

子序列计数的问题是一类典型的dp,我回头专门讲一下。大概就是:求子序列的DP,一般对于某个元素可以区分:选/不选,来做。求两个子序列可以区分:不选/选进序列1/选进序列2,三种转移。

代码

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#if !defined(ONLINE_JUDGE) && defined(LOCAL)
#include "helper.h"
#else
#define dbg(...) ;
#define local_go_m(x) int c;cin>>c;while(c--)x()
#endif
constexpr int M = 998244353;
template<class T>
constexpr T power(T a, i64 b) {
T res = 1;
for (; b != 0; b /= 2, a *= a) {
if (b & 1) {
res *= a;
}
}
return res;
}
template<int M>
struct ModInt {
public:
constexpr ModInt() : x(0) {}
template<std::signed_integral T>
constexpr ModInt(T x_) {
T v = x_ % M;
if (v < 0) {
v += M;
}
x = v;
}
constexpr int val() const {
return x;
}
constexpr ModInt operator-() const {
ModInt res;
res.x = (x == 0 ? 0 : M - x);
return res;
}
constexpr ModInt inv() const {
return power(*this, M - 2);
}
constexpr ModInt &operator*=(const ModInt &rhs) &{
x = i64(x) * rhs.val() % M;
return *this;
}
constexpr ModInt &operator+=(const ModInt &rhs) &{
x += rhs.val();
if (x >= M) {
x -= M;
}
return *this;
}
constexpr ModInt &operator-=(const ModInt &rhs) &{
x -= rhs.val();
if (x < 0) {
x += M;
}
return *this;
}
constexpr ModInt &operator/=(const ModInt &rhs) &{
return *this *= rhs.inv();
}
friend constexpr ModInt operator*(ModInt lhs, const ModInt &rhs) {
lhs *= rhs;
return lhs;
}
friend constexpr ModInt operator+(ModInt lhs, const ModInt &rhs) {
lhs += rhs;
return lhs;
}
friend constexpr ModInt operator-(ModInt lhs, const ModInt &rhs) {
lhs -= rhs;
return lhs;
}
friend constexpr ModInt operator/(ModInt lhs, const ModInt &rhs) {
lhs /= rhs;
return lhs;
}
friend constexpr std::istream &operator>>(std::istream &is, ModInt &a) {
i64 i;
is >> i;
a = i;
return is;
}
friend constexpr std::ostream &operator<<(std::ostream &os, const ModInt &a) {
return os << a.val();
}
friend constexpr std::strong_ordering operator<=>(ModInt lhs, ModInt rhs) {
return lhs.val() <=> rhs.val();
}
private:
int x;
};
using Z = ModInt<M>;
template<typename T>
struct Comb {
std::vector<T> fac;
std::vector<T> facInv;
int n;
Comb(int n_) {
n = n_;
fac.assign(n, T{});
facInv.assign(n, T{});
fac[0] = 1;
for (int i = 1; i < n; i++) {
fac[i] = fac[i - 1] * i;
}
for (int i = 0; i < n; i++) {
facInv[i] = fac[i].inv();
}
}
};
constexpr int COMB_N = 300300;
Comb<Z> comb(COMB_N);
template<std::signed_integral T>
Z P(T n, T m) {
assert(n >= 0 && m >= 0 && m <= n);
if (n < comb.n) {
return comb.fac[n] * comb.facInv[n - m];
} else {
T v = n, rnd = m;
Z res = 1;
while (rnd--) {
res *= v--;
}
return res;
}
}
template<std::signed_integral T>
Z C(T n, T m) {
return P(n, m) * comb.facInv[m];
}
void go() {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
vector<Z> f(n, 0);
int c1 = 0;
Z res = 0;
for (int i = 0; i < n; i++) {
if (a[i] == 1) {
if (i) f[i] = f[i - 1];
c1++;
} else if (a[i] == 3) {
if (i) f[i] = f[i - 1];
res += f[i];
} else {
if (i) f[i] = f[i - 1] * 2;
f[i] += c1;
}
}
dbg(f);
cout << res << endl;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
local_go_m(go);
return 0;
}

本文作者:califeee

本文链接:https://www.cnblogs.com/califeee/p/18729058

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   califeee  阅读(5)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.