当前位置: 首页 > news >正文

Codeforces Round 1051 (Div. 2) 补题记录

Codeforces Round 1051 (Div. 2) 补题记录

D - Inversion Graph Coloring

题目大意:

当一个序列 \(b_1, b_2, \dots, b_k\) 存在一种对每个下标 \(i\) 染上红色或蓝色的方式,使得每一对 \(i < j\)\(b_i > b_j\) 的下标 \(i, j\) 的颜色不同时,我们称这个序列是“好”的。

给定一个序列 \(a_1, a_2, \dots, a_n\),计算它“好”的子序列数量,并对 \(10^9 + 7\) 取模。

思路:

考虑什么样的子序列会被计入答案。注意到,当存在下标 \(i < j < k\)\(a_i > a_j > a_k\) 时,不存在合法的染色方案。因此题目可以转化为求最长递减子序列长度小于等于 \(2\) 的子序列个数。

接着我们考虑对于第 \(i\) 个数,会与前面已经组成的哪些子序列形成新的子序列。

  • 加入最大值 \(j \leq a_i\) 的子序列中。此时由 \(a_i\) 组成的递减子序列长度为 \(1\)

  • 加入最长递减子序列长度为 \(2\) 且末尾数值 \(k \leq a_i < j\) 的子序列中。此时,\(a_i\) 代替 \(k\) 成为最长递减子序列的最后一个元素,长度依旧为 \(2\)

根据上面的两种情况以及不选择第 \(i\) 个元素与前面元素构成子序列的情况,我们进行 \(dp\),状态转移如下:

  • 不选择 \(a_i\)\(dp[i][j][k] \leftarrow dp[i - 1][j][k];\)

  • \(j \leq a_i\)\(dp[i][a_i][k] \leftarrow dp[i - 1][j][k];\)

  • \(k \leq a_i < j\)\(dp[i][j][a_i] \leftarrow dp[i - 1][j][k].\)

时间复杂度 \(O(n^3)\) 足够通过本题的 Easy Version。

接着我们考虑如何优化 \(dp\)

注意到在转移时,存在如下关系:

\[\begin{cases} dp[i][a_i][k] = \sum_{j \leq a_i} dp[i - 1][j][k] \\ \\ dp[i][j][a_i] = \sum_{k \leq a_i} dp[i - 1][j][k] \end{cases} \]

因此可以考虑把第一维砍掉,用树状数组维护 \(dp\) 每行每列的前缀和,求出增量即可。

\(code:\)

#include <bits/stdc++.h>
using namespace std;#define endl '\n'
#define i64 long longconst int mod = 1000000007;template <typename T>
struct Fenwick {int n;std::vector<T> a;Fenwick(int n = 0) {init(n);}void init(int n) {this->n = n;a.assign(n, T());}void add(int x, T v) {for (int i = x + 1; i <= n; i += i & -i) {a[i - 1] += v;}}T sum(int x) {auto ans = T();for (int i = x; i > 0; i -= i & -i) {ans += a[i - 1];}return ans;}T rangeSum(int l, int r) {return sum(r) - sum(l);}
};void MuBai() {int n;cin >> n;vector<int> a(n + 1);for (int i = 1; i <= n; i ++ ) cin >> a[i];vector<Fenwick<i64>> row(n + 1), col(n + 1);for (int i = 0; i <= n; i ++ ) {row[i].init(n + 1);col[i].init(n + 1);}row[0].add(0, 1), col[0].add(0, 1);vector f(n + 1, vector<i64>(n + 1, 0));for (int i = 1; i <= n; i ++ ) {for (int j = 0; j <= n; j ++ ) {i64 g = col[j].sum(a[i] + 1) % mod;i64 h = (a[i] < j) ? (row[j].sum(a[i] + 1) % mod) : 0;if (g) {row[a[i]].add(j, g);col[j].add(a[i], g);f[a[i]][j] += g;if (f[a[i]][j] >= mod) f[a[i]][j] -= mod;}if (h) {row[j].add(a[i], h);col[a[i]].add(j, h);f[j][a[i]] += h;if (f[j][a[i]] >= mod) f[j][a[i]] -= mod;}}}i64 ans = 0;for (int i = 0; i <= n; i ++ ) {ans += col[i].sum(n + 1) % mod;if (ans >= mod) ans -= mod;}cout << (ans < mod ? ans : ans - mod) << endl;
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr), cout.tie(nullptr);int t; cin >> t;while (t -- ) MuBai();return 0;
}
http://www.gsyq.cn/news/63406.html

相关文章:

  • Motia:未来平台
  • DC-2渗透测试 - fish666
  • k8s基本对象详解
  • BLOG迁移: 从Halo + CF Tunnel 到 Hugo + github + Cloudflare page
  • API设计最佳实践 - 智慧园区
  • 第4单元检测卷
  • ubunutu连接蓝牙键盘鼠标
  • 详细介绍:从 1.0 到 13.0:C# 十八年进化史,一部写给开发者的语言成长记
  • 生研界:技术赋能,AI如何重塑医学科研生态?
  • 第6单元检测卷
  • 2025 年江苏有机农场推荐榜:德芳有机农场全品类覆盖、国家权威有机认证
  • S7-1200 PROFINET与 IO device 通信
  • 干货|2025NCUK机构择优指南:官方授权中心排名对比+教学体系深度解析
  • python的日志使用装饰器,记录的日志文件记录
  • 【pandas基础】用Pandas处理泰坦尼克号获救数据
  • why I can not fully accept měigu is good
  • is měigu good
  • Day26透明度
  • 自指自洽,磨砺洗礼,人非圣贤,孰能无过?塞翁失马,焉知非福?
  • MateChat + DevUI + DeepSeek:教育智能答疑助手改造实践
  • 量子计算新突破:高精度量子比特控制技术
  • CAD 二次开发应用 获取统计单行字体内的特定数据
  • CF2157E Adjusting Drones
  • JSON序列化类
  • Educational Codeforces Round 146 简解
  • 选购攻略!2025 厨余处理器 7大品牌,中餐适配款优先级推荐
  • WPF populate BooksCollection via Dispatcher.InvokeAsync,DispatcherPriority.Background in mvvm
  • 2025 年 12 月 AMC12 竞赛备考:上海补课机构优选,选对助力高效冲分
  • 2025年度绍兴交通事故优秀律师推荐|聚焦实力与口碑
  • 最小链覆盖 - Dilworth 定理 小记