Codeforces Round 1051 (Div. 2) D1D2题解

news/2025/9/22 18:52:15/文章来源:https://www.cnblogs.com/mrjiege/p/19105838

D1. Inversion Graph Coloring (Easy Version)

题意:

给定一个序列 \(a_1, a_2, \ldots, a_n\),我们需要计算其“好”子序列的数量。一个子序列是“好”的,如果存在一种将它的索引染成红色或蓝色的方式,使得对于任何一对索引 \(i < j\) 且子序列中 \(b_i > b_j\),索引 \(i\)\(j\) 的颜色不同。换句话说,子序列的逆序图是二分图。

思路:

经分析,一个子序列是“好”的当且仅当它不包含长度为 3 的递减子序列(即没有三个元素 \(b_i > b_j > b_k\)\(i < j < k\))。因此,问题转化为计算序列中所有不包含长度为 3 的递减子序列的子序列的数量

由于 $n \leq 300 $ 且所有测试用例的 $ n $ 总和不超过 300,我们可以使用动态规划(DP)来高效计数。

DP 状态设计

定义 DP 状态 ( dp[j][k] ) 表示当前子序列的最大值为 ( j )、次大值为 ( k ) 的子序列数量。其中 ( j ) 和 ( k ) 是序列中的值(范围从 0 到 ( n ),0 用于表示空状态)。初始状态 ( dp[0][0] = 1 ) 代表空子序列。

状态转移

遍历序列中的每个元素$ ( a_i )$ 时,对于每个状态 \((j, k)\) ,我们考虑两种选择:

  1. 不选当前元素:状态不变,即 $ dp[j][k] $ 贡献到新状态 $ cp[j][k]$。
  2. 选当前元素:根据 $ a_i $ 与当前最大值 $ j $ 和次大值 $ k $ 的关系更新状态:
    • 如果 \(( a_i \geq j )\),添加后新最大值为 ( a_i ),次大值为 ( j ),状态转移到 ( cp[a_i][j] )。
    • 如果 \(( a_i < j )\)\(( a_i \geq k )\),添加后最大值不变,次大值更新为 \(( a_i )\),状态转移到 \(( cp[j][a_i] )\)
    • 如果 \(( a_i < k )\),添加后会形成三个递减元素 \(( j > k > a_i )\),因此不能选,跳过。

这样确保所有计数的子序列都不包含长度为 3 的递减子序列。

代码

#include<bits/stdc++.h>
#define ll long long
#define ce cerr
#define ull unsigned long long
#define lll __int128
#define PII pair<int, int>
#define PLL pair<long ,long>
#define int long long
using namespace std;const int inf = 0x3f3f3f3f;
const ll iinf = 1e18;
const int N = 310;
const int mod = 1e9 + 7;int t;void solve() {int n;cin >> n;vector<int> a(n + 1);for (int i = 0; i < n; ++i) {cin >> a[i];}// dp[j][k] 表示当前子序列的最大值为 j,次大值为 k 的子序列数量vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0));dp[0][0] = 1; // 初始状态:空子序列for (int i = 0; i < n; ++i) {vector<vector<int>> cp(n + 1, vector<int>(n + 1, 0)); // 临时状态矩阵for (int j = 0; j <= n; ++j) {for (int k = 0; k <= n; ++k) {// 不选当前元素 a[i]cp[j][k] = (cp[j][k] + dp[j][k]) % mod;// 选当前元素 a[i]if (a[i] >= j) {// 新最大值是 a[i],次大值是 jcp[a[i]][j] = (cp[a[i]][j] + dp[j][k]) % mod;} else if (a[i] >= k) {// 最大值不变,次大值更新为 a[i]cp[j][a[i]] = (cp[j][a[i]] + dp[j][k]) % mod;} else {// 如果 a[i] < k,添加会形成三个递减,跳过continue;}}}dp = cp; // 更新状态}ll res = 0;// 求和所有状态的值for (int i = 0; i <= n; ++i) {for (int j = 0; j <= n; ++j) {res = (res + dp[i][j]) % mod;}}cout << res << "\n";
}signed main() {ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);t = 1;cin >> t;while (t--) {solve();}return 0;
}

D2. Inversion Graph Coloring (Hard Version)

题意:

同前,でも\(n = 2000\)

思路:

\(dp[j][k]\) 表示:已经选的子序列中两种颜色各自最后一个元素的值(分别记为 \(j\)\(k\))。
遍历新元素 \(v = a[i]\) 时,只会修改两类位置:行 \(\boxed{j == v}\) (把元素放到颜色1)和列 \(\boxed{k == v}\) (把元素放到颜色2,且 \(j > v\))。因此不必在每一步重建整个 \(n \times n\) 表格,只需要对这两类位置做增量更新。
对于行更新需要按列查询列前缀和:\(\sum_{j=0}^{v} dp[j][k]\),为此给每一列维护一个 Fenwick(按 \(j\) 的维度做前缀和)。
对于列更新需要按行查询行前缀和:\(\sum_{k=0}^{v} dp[j][k]\),为此给每一行维护一个 Fenwick(按 \(k\) 的维度做前缀和)。
每次把增量写回 \(dp\) 的同时,立刻更新对应的行/列 Fenwick(因为这些增量只会影响未来元素的查询,但对本次同一列/同行的查询顺序不会产生交叉影响,按上面顺序逐项处理即可安全使用)。

代码

#include<bits/stdc++.h>
#define ll long long
#define ce cerr
#define ull unsigned long long
#define lll __int128
#define PII pair<int, int>
#define PLL pair<long ,long>
#define int long long
using namespace std;const int inf = 0x3f3f3f3f;
const ll iinf = 1e18;
const int N = 310;
const int MOD = 1e9 + 7;
//cin.ignore(std::numeric_limits< streamsize >::max(), '\n');
int t;
//dp[i][j]
struct Fenwick {int n; vector<int> bit;Fenwick() : n(0) {}Fenwick(int _n) { init(_n); }void init(int _n) {n = _n; // we will use positions 0..(n-1) if _n is countbit.assign(n + 5, 0);}// add val to position pos (pos in [0..n-1])void add(int pos, int val) {if (val == 0) return;int i = pos + 1;while (i <= n) {bit[i] += val;if (bit[i] >= MOD) bit[i] -= MOD;i += i & -i;}}// sum of [0..pos], pos in [-1..n-1]int sumPrefix(int pos) {if (pos < 0) return 0;int i = pos + 1;int res = 0;while (i > 0) {res += bit[i];if (res >= MOD) res -= MOD;i -= i & -i;}return res;}
};
void solve() {int n;cin >> n;vector<int> a (n + 1);for (int i = 0; i < n; ++i) {cin >> a[i];}// dp[j][k], j,k in [0..n]vector<vector<int> > dp (n + 1, vector<int> (n + 1, 0));   dp[0][0] = 1;// vec1 = rowFen[j] (for fixed j, prefix over k)// vec2 = colFen[k] (for fixed k, prefix over j)vector<Fenwick> vec1 (n + 1), vec2 (n + 1);for (int i = 0; i <= n; ++i) {vec1[i].init(n + 1);vec2[i].init(n + 1);}// initial statevec1[0].add(0, 1);vec2[0].add(0, 1);for (int idx = 0; idx < n; ++idx) {int v = a[idx]; // 1..n// 1) 把当前元素放到“颜色1”的末尾 -> 更新行 j == v:// 对每个 k in [0..n]: dp[v][k] += sum_{j=0..v} dp[j][k]  (colFen[k].sumPrefix(v))for (int k = 0; k <= n; ++k) {int addVal = vec2[k].sumPrefix(v);if (addVal == 0) continue;dp[v][k] += addVal;if (dp[v][k] >= MOD) dp[v][k] -= MOD;vec1[v].add(k, addVal);   // 更新 rowFen[v] 的 k 位置vec2[k].add(v, addVal);   // 更新 colFen[k] 的 j=v 位置}// 2) 把当前元素放到“颜色2”的末尾 -> 更新列 k == v,但只有 j > v 才走这条// 对每个 j in (v..n]: dp[j][v] += sum_{k=0..v} dp[j][k] (rowFen[j].sumPrefix(v))for (int j = v + 1; j <= n; ++j) {int addVal = vec1[j].sumPrefix(v);if (addVal == 0) continue;dp[j][v] += addVal;if (dp[j][v] >= MOD) dp[j][v] -= MOD;vec1[j].add(v, addVal);vec2[v].add(j, addVal);}}ll res = 0;for (int i = 0; i <= n; ++i) {for (int j = 0; j <= n; ++j) {res = (res + dp[i][j]) % MOD;}}cout << res << "\n";
}
signed main() {ios::sync_with_stdio (false);cin.tie(NULL);cout.tie(NULL);t = 1;cin >> t;while (t --) {solve();}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/910034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站备案名称中国开头选课网站开发

雷迪斯and the乡亲们 欢迎你们来到 奇幻的编程世界 17.wc命令 作用&#xff1a; 统计行数、单词数、字符分数 格式&#xff1a; wc 选项 文件 选项&#xff1a; -l&#xff1a; 统计行数 -w&#xff1a; 统计单词 -c &#xff1a;统计字符 例子&#xff1a; 162&…

每日报告-关于本学期的计划

每日报告-关于本学期的计划1.确定100人次的社会调研的主题 选题:你觉得市面上缺少哪种APP/你还需要什么APP

阿里云 ip 网站东莞网站seo优化托管

1、简单介绍 继前面发布的 GroundingDino 和 Open-GroundingDino的推理 和 Open-GroundingDino的训练实现&#xff0c;作为 GroundingDino延续性的文本检测网络 MM-Grounding-DINO 也发布了较详细的 训练和推理实现教程&#xff0c;而且操作性很强。作为学习内容&#xff0c;也…

青海建设厅报名网站基于html5的网站开发

Shell 教程 Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问操作系统内核的服务。 Ke…

长春建站最新消息经典营销案例分析

-Xms256m -Xmx256m -XX:MaxPermSize64m 如果 jvm 启动失败&#xff0c; 说堆内存不够&#xff0c; 需要调小 初始堆和最大堆大小&#xff0c; 持久代大小&#xff1b; 第一行的参数是调节后的vm参数荔枝 &#xff1b;

网站免费正能量小说家用电脑做网站后台

一、前言各位小伙伴们还有几天新的一年即将来临&#xff0c;这篇文章作为今年的结束吧。不知道大家对自己每一年的技术发展规划是什么&#xff0c;我在这里分享一下我2021年的新的规划&#xff0c;这里非常感谢各位小伙伴对我的关注。二、内容概要2021的布局客户端技术分享服务…

浙江建设厅网站安全员证书查询wordpress添加新建标签页

在最近结束的 VMware Explore 2023 拉斯维加斯大会上&#xff0c;VMware 推出了新的 Private AI 产品&#xff0c;以促进企业采用生成式人工智能并挖掘可信数据的价值。VMware 宣布了以下几点&#xff1a; 与 NVIDIA 合作推出 VMware Private AI Foundation&#xff0c;将两家…

凡科网站怎么做授权查询黑龙江建设网证书查询官网

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之QRCode组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、QRCode组件 用于显示单个二维码的组件。 子组件 无。 接口 QRCode(value: st…

网站访客qq提取牙克石网站建设

浏览器的几种存储方式&#xff08;图表形式&#xff09; 存储方式特点应用场景示例有效期容量是否共享安全性Cookie存储少量数据&#xff0c;例如用户偏好、登录状态等用户认证、个性化设置登录状态、语言偏好会话或永久4KB同源中等Local Storage️永久存储数据&#xff0c;同…

织梦小说网站模板下载地址商品展示的网站源码

实物 该转换器在后备箱放了一段时间&#xff0c;就成这个样子了&#xff0c;当然&#xff0c;后备箱也比较恶劣&#xff0c;堪比盐雾试验&#xff0c;因为有瓶稀盐酸倒了&#xff0c;发现不及时&#xff0c;一个新的转换器就成这个样子了。 VGA转HDMI转换器VGA输入插头 VGA转…

深圳龙华做网站的公司湖北建设厅网站上查询

今天分享的AIGC系列深度研究报告&#xff1a;《AIGC专题报告&#xff1a;ChatGPT的工作原理》。 &#xff08;报告出品方&#xff1a;省时查&#xff09; 报告共计&#xff1a;107页 前言 ChatGPT 能够自动生成一些读起来表面上甚至像人写的文字的东西&#xff0c;这非常了不…

若依前后端分离版本二次开发(一 搭建开发环境,新建模块)

若依前后端分离版本二次开发(一 搭建开发环境,新建模块)一 修订记录序号 修订内容 修订时间1 新增二 目标 2.1 初始化环境 2.2 新增模块 三 实施 3.1 初始化环境 3.1.1 开发环境信息序号 软件名称 版本1 ruoyi 前后…

Python开发中都遇到哪些问题,怎么解决的

Python开发中都遇到哪些问题,怎么解决的Python开发中高频问题集中在环境依赖、性能瓶颈、并发安全、代码规范等维度,以下是具体场景及可落地的解决方案,结合实际开发经验总结: 一、环境与依赖问题依赖版本冲突(“…

网站后台网址忘记了 php室内装修设计图用什么软件

本题要求对两个正整数m和n&#xff08;m≤n&#xff09;编写程序&#xff0c;计算序列和m​2​​1/m(m1)​2​​1/(m1)⋯n​2​​1/n。 输入格式: 输入在一行中给出两个正整数m和n&#xff08;m≤n&#xff09;&#xff0c;其间以空格分开。 输出格式: 在一行中按照“sum S”的…

【废话】

【废话】原来有种最宝贵的东西是,在你拥有的瞬间失去了它

html5高端酒水饮料企业网站模版天津地铁建设网站

1.窗口函数之排序函数 RANK, DENSE_RANK, ROW_NUMBER RANK函数 计算排序时,如果存在相同位次的记录,则会跳过之后的位次 有 3 条记录排在第 1 位时: 1 位、1 位、1 位、4 位…DENSE_RANK函数 同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次 有 3 条记录排在…

内网网站建设的步骤过程怎么做自己淘宝优惠券网站

腾讯云0基础搭建帕鲁服务器4C16G14M服务器稳定无卡顿&#xff0c;先下载SteamCMD&#xff0c;并运行&#xff1b;然后下载Palserver&#xff0c;修改服务ini配置&#xff0c;启动PalServer&#xff0c;进入游戏服务器。腾讯云百科txybk.com分享腾讯云创建幻兽帕鲁服务器教程&am…

zencart 网站入侵珠海seo

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 左右遍历2. 进阶&#xff1a;常数空间遍历&#xff0c;升序降…

免费网站建设模版下载网页版梦幻西游辅助工具

网上都是怎么用 gitlab&#xff0c;但是实际开发中有需要针对 gitlab 进行二次编译自定义实现功能的想法。 搜索了网上的资料以及在官网的查找&#xff0c;查到了如下 gitlab 使用 ruby 开发。 gitlab 下载包 gitlab/gitlab-ce - Packages packages.gitlab.com gitlab/gitl…

网站建设前期规划方案范文ui设计培训资料

前言&#xff1a;小伙伴们又见面啦&#xff01;本期内容&#xff0c;博主将展开讲解有关C语言中指针的上半部分基础知识&#xff0c;一起学习起来叭&#xff01;&#xff01;&#xff01; 目录 一.什么是指针 二.指针类型 1.指针的解引用 2.指针-整数 三.野指针 1.野指针…