2024CCPC 女生专场

news/2025/4/1 22:33:59/文章来源:https://www.cnblogs.com/noSananoLife/p/18801270

目录
  • D - Excellent Splitting
    • Description
    • Solution
    • Code

D - Excellent Splitting

Description

有一个长度为 \(N\) 的排列 \(P\),将 \(P\) 拆成 \(A\)\(B\),求 \(A\) 的最长上升子序列的长度与 \(B\) 的最长下降子序列的长度相加的最大值。

数据范围:\(1\leqslant N\leqslant 2×10^5\).

Solution

首先一个很重要的结论是,设 LIS/LDS 分别为序列的最长上升/下降子序列长度,答案一定是 LIS+LDS 或者 LIS+LDS-1.

这是因为序列的 LIS 和 LDS 最多重复一个数字,因为要求 严格 上升/下降。

于是只用判断:无论怎么选,上升子序列和下降子序列必定存在一个交点。

使用二元组 \((len,cnt)\) 维护数据,表示最长上升/下降子序列长度为 \(len\),选择子序列方案数为 \(cnt\).

使用 \(f_{0/1,i}\) 表示以 \(i\) 为结尾(\(0\))/开头(\(1\))的最长上升子序列,而 \(g_{0/1,i}\) 表示最长下降子序列。这两个数组均需维护上述二元组。

最后,计算出 \(c_0\) 为全局 LIS 的方案数,\(c_1\) 为全局 LDS 的方案数。那么 \(c_0·c_1\) 表示 LIS 和 LDS 的所有可能匹配。

接着计算 \(h_{0/1,i}\) 表示包含 \(i\) 的最长上升(\(0\))/下降(\(1\))子序列的方案数。于是我们只用比较 \(\sum h_{0,i}\cdot h_{1,i}\)\(c_0·c_1\) 是否相等,如果相等则无论怎么选,上升子序列和下降子序列必定存在一个交点。

这题非常坑爹的一个点是,方案数这一维会爆 long long,不能直接比较,需要自行设定一个模数计算。我用了 \(10^9+7\).

Code

# include <cstdio>
# include <cctype>
# define print(x,y) write(x), putchar(y)template <class T>
inline T read(const T sample) {T x=0; bool f=0; char s;while(!isdigit(s=getchar())) f|=(s=='-');for(; isdigit(s); s=getchar()) x=(x<<1)+(x<<3)+(s^48);return f? -x: x;
}
template <class T>
inline void write(T x) {static int writ[50], w_tp=0;if(x<0) putchar('-'), x=-x;do writ[++w_tp]=x-x/10*10, x/=10; while(x);while(putchar(writ[w_tp--]^48), w_tp);
}# include <set>
# include <cmath>
# include <vector>
# include <cstring>
# include <iostream>
# include <algorithm>
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;const int MAXN = 2e5+5;
const int mod = 1e9+7;int n, a[MAXN];
ll h[2][MAXN];
struct node {int len; ll cnt;
} c[2][MAXN], f[2][MAXN], g[2][MAXN];int lowbit(int x) { return x&-x; }node merge(node x, node y) {if(x.len ^ y.len)return (x.len<y.len)? y: x;return (node){x.len, (x.cnt+y.cnt)%mod};
}void add0(int x, node k) {for(int i=x; i<=n; i+=lowbit(i))c[0][i] = merge(c[0][i], k);
}void add1(int x, node k) {for(int i=x; i>0; i-=lowbit(i))c[1][i] = merge(c[1][i], k);
}node ask0(int x) {node ret = (node){0, 1};for(int i=x; i>0; i-=lowbit(i))ret = merge(ret, c[0][i]);return ret;
}node ask1(int x) {node ret = (node){0, 1};for(int i=x; i<=n; i+=lowbit(i))ret = merge(ret, c[1][i]);return ret;
}void reset() {for(int i=1; i<=n; ++i)c[0][i] = (node){0, 0},c[1][i] = (node){0, 0};
}void noSananoLife() {n = read(9);for(int i=1; i<=n; ++i) a[i]=read(9);reset();for(int i=1; i<=n; ++i) {node ret0 = ask0(a[i]-1);node ret1 = ask1(a[i]+1);f[0][i] = (node){ret0.len+1, ret0.cnt};g[0][i] = (node){ret1.len+1, ret1.cnt};add0(a[i], f[0][i]);add1(a[i], g[0][i]);}reset();for(int i=n; i>=1; --i) {node ret0 = ask0(a[i]-1);node ret1 = ask1(a[i]+1);g[1][i] = (node){ret0.len+1, ret0.cnt};f[1][i] = (node){ret1.len+1, ret1.cnt};add0(a[i], g[1][i]);add1(a[i], f[1][i]);}int LIS=0, LDS=0;for(int i=1; i<=n; ++i)LIS = max(LIS, f[0][i].len),LDS = max(LDS, g[0][i].len);ll c0=0, c1=0;for(int i=1; i<=n; ++i)c0 += (LIS==f[0][i].len)? f[0][i].cnt: 0,c1 += (LDS==g[0][i].len)? g[0][i].cnt: 0;c0 %= mod, c1 %= mod;for(int i=1; i<=n; ++i) {if(f[0][i].len+f[1][i].len-1 == LIS)h[0][i] = f[0][i].cnt%mod*(f[1][i].cnt%mod)%mod;else h[0][i] = 0;if(g[0][i].len+g[1][i].len-1 == LDS)h[1][i] = g[0][i].cnt%mod*(g[1][i].cnt%mod)%mod;else h[1][i] = 0;}ll all = 0;for(int i=1; i<=n; ++i)all = (all+h[0][i]*h[1][i]%mod)%mod;print(LIS+LDS-(all==c0*c1%mod), '\n');
}int main() {for(int T=read(9); T; --T)noSananoLife();return 0;
}   



未完待更。




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

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

相关文章

Pychaim集成本地部署的ollama+qwen-coder32b

服务器配置为:2个11264MiB NvidiaGPU + 16核 3.8GHz CPU + 72G 内存;部署Ollama平台,使用Qwen-coder2.5:32B模型。 1. 下载、安装并运行ollama; ollama的安装网上介绍的比较多,此处不再多讲,可以参考 Ollama全面指南:安装、使用与高级定制 若在服务器上部署ollama,确保…

[Vue] Vue 模板编译原理解析 part3

生成 JavaScript AST 我们要对整个模板的 AST 进行转换,转换为 JS AST。 我们目前的代码已经有了遍历模板 AST,并且针对不同的节点,做不同操作的能力。 我们首先需要知道 JS AST 长什么样子: function render(){return null; }上面的代码,所对应的 JS AST 如下图所示:这里…

[Vue] Vue模板编译原理解析 part3

生成 JavaScript AST 我们要对整个模板的 AST 进行转换,转换为 JS AST。 我们目前的代码已经有了遍历模板 AST,并且针对不同的节点,做不同操作的能力。 我们首先需要知道 JS AST 长什么样子: function render(){return null; }上面的代码,所对应的 JS AST 如下图所示:这里…

关于window版本nacos版本安装过程

环境 window10 16G 1TB下载地址window版本zip包 https://github.com/alibaba/nacos/releases/download/2.5.1/nacos-server-2.5.1.zip Linux版tar包 https://github.com/alibaba/nacos/releases/download/2.5.1/nacos-server-2.5.1.tar.gz安装前提安装jdk 1.8及以上,我安装了…

Netty源码—10.Netty工具之时间轮

大纲 1.什么是时间轮 2.HashedWheelTimer是什么 3.HashedWheelTimer的使用 4.HashedWheelTimer的运行流程 5.HashedWheelTimer的核心字段 6.HashedWheelTimer的构造方法 7.HashedWheelTimer添加任务和执行任务 8.HashedWheelTimer的完整源码 9.HashedWheelTimer的总结 10.Hashe…

0330-好的开始是成功的一半

前言 今天帮一个 USC Game Dev 专业同学做项目,真的挺复杂的一个项目。 但是我依然把项目配置好了,后面就是慢慢的添加新功能。 我用了 git 管理这个项目,把自己的每一步关键操作都用 git commit 记录一下。效果心路历程 我想过很多次 “要不就放弃吧” 但是看到旁边的“Att…

数仓项目建设方案——维度建模

数仓项目建设方案——维度建模式信息收集项目背景 阐述公司当前的行业,涉及的主要业务,相关数据的大小、分布、更新情况描述,需要解决的相关问题。公司当前数据建设现状 使用的数据库、数据来源系统与方式、现有数据分析组织,所使用的 BI 工具与数仓工具、为什么建立以及当…

在机器人和无人机时代,测绘人的出路在哪里?

一、技术革命:当测绘行业按下“加速键”无人机与机器人技术正在重塑测绘行业的底层逻辑。传统测绘依赖人工作业,效率低、成本高且风险大,而无人机凭借其灵活性和高效性,已能快速完成大范围地形测绘,精度可达厘米级,甚至替代人工进入危险区域(如塌方、悬崖等)作业。例如…

openwrt禁止设备联网

一、代码操作 把mac地址换成要禁用的设备mac地址,加到自定义防火墙最后,记得最后重启防火墙生效 /etc/init.d/firewall restart iptables -I INPUT -m mac --mac-source B8:C7:4A:7A:66:2E -j DROP iptables -I FORWARD -m mac --mac-source B8:C7:4A:7A:66:2E -j DROP iptab…

JVM调优原理篇

JVM调优 什么是JVM调优,调优的指标是什么? JVM调优指的就是对当前系统进行性能调优,简单来说就是尽可能使用较小的内存和CPU来让JAVA程序获得更高的吞吐量及较低的延迟。 调优常见的指标:吞吐量:是指不考虑垃圾收集引起的停顿时间或内存消耗,应用达到的最高性能指标。 延…

20241216 实验二《Python程序设计》实验报告

20241216 2024-2025-2 《Python程序设计》实验二报告 课程:《Python程序设计》 班级: 2412 姓名: 曾楷 学号:20241216 实验教师:王志强 实验日期:2024年3月26日 必修/选修: 公选课 (一) 实验内容 1.设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善…

[Windows] TechSweeper 应用程序卸载神器V1.2.1

一.我们改进了程序元素显示,现在超出列宽,可以进行滚动显示二.我们为程序添加了右键菜单,现在功能更加全面三.现在程序出现崩溃时,可以进行错误提示与收集四.现在程序可以进行主题切换了五.添加了作者相关信息六.现在可以打开程序相关注册表了(直接显示 清晰明了)七.现在可…