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

CF946G Almost Increasing Array 题解

Solution

弱化版

首先不考虑删数操作,考虑至少修改数组中多少个数才能使其单调递增。

转而考虑未被修改的数必须满足的条件。若最终 \(a_i,a_j(i<j)\) 均未被修改,则有 \(j-i\le a_j-a_i\),即 \(a_i-i\le a_j-j\)。反过来,也能证明任意一个满足该条件的子序列一定能均不被修改。因而问题转化为求 \(n\) 减序列 \(\{a_i-i\}\) 的 LIS 长度。

考虑经典 \(O(n\log n)\) LIS 做法。设 \(f_i\) 为当前长 \(i\) 的不降序列最小末尾(如果不存在则 \(f_i=+\infty\))。每次二分找到最小的 \(k\) 使得 \(f_k\le a_i\) 并令 \(f_{k+1}\leftarrow\min(f_{k+1},a_i)\)。答案即为 \(n-\max(\{k|f_k<+\infty\})\)

原题

删数操作可以提至所有修改之前。

同理设 \(g_i\) 为当前已删除一个数时,长 \(i\) 的不降序列最小末尾(删的数不算)。

然后分讨 \(a_i\) 是否删除,共有三个操作。

  • \(a_i\) 删除:对于所有 \(k\)\(g_k\leftarrow \min(g_k,f_k)\)(操作 \(1\))。
  • \(a_i\) 不删除:
    • \(a_i-i\) 更新 \(f\)(操作 \(2\))。
    • \(a_i-i+1\) 更新 \(g\)。因为前面已经删了一个数,所以 \(a_i\) 实际下标为 \(i-1\)。(操作 \(3\))。

为了避免错误的覆盖,需要按 \(3\to 1\to 2\) 的顺序执行三个操作。

然后使用线段树维护 \(f,g\) 即可,时间复杂度 \(O(n\log n)\)

Code

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i(a);i<b;++i)
#define rept(i,a,b) for(int i(a);i<=b;++i)
#define ls(p) ((p)<<1)
#define rs(p) ((p)<<1|1)
using namespace std;
constexpr int N=2e5+5,INF=1.1e9;
int n,x,f[N<<2],g[N<<2];
bool tag[N<<2];
void add_tag(int p){tag[p]=true;g[p]=min(g[p],f[p]);
}
void push_up(int p){f[p]=min(f[ls(p)],f[rs(p)]);g[p]=min(g[ls(p)],g[rs(p)]);
}
void push_down(int p){if(tag[p]){add_tag(ls(p));add_tag(rs(p));tag[p]=0;}
}
int get(int tree[],int p,int pl,int pr,int x){  // 查找最后一个<=x的下标if(pl==pr) return pl;int mid=pl+pr>>1;push_down(p);if(tree[rs(p)]>x) return get(tree,ls(p),pl,mid,x);return get(tree,rs(p),mid+1,pr,x);
}
void upd(int tree[],int p,int pl,int pr,int pos,int x){  // 单点更新if(pl==pr){tree[p]=min(tree[p],x);return;}int mid=pl+pr>>1;push_down(p);if(pos<=mid) upd(tree,ls(p),pl,mid,pos,x);else upd(tree,rs(p),mid+1,pr,pos,x);push_up(p);
}
signed main(){cin.tie(0)->sync_with_stdio(0);cin>>n>>x;fill(f+1,f+(n<<2),INF);fill(g+1,g+(n<<2),INF);// 以i=1时为初始值upd(f,1,0,n,0,-INF);  // f[0]=-INFupd(f,1,0,n,1,x-1);  // f[1]=a[1]-1upd(g,1,0,n,0,-INF);  // g[0]=-INFrept(i,2,n){cin>>x;upd(g,1,0,n,get(g,1,0,n,x-i+1)+1,x-i+1);  // 操作3add_tag(1);  // 操作1upd(f,1,0,n,get(f,1,0,n,x-i)+1,x-i);  // 操作2}cout<<n-1-get(g,1,0,n,INF-1);return 0;
}
http://www.jsqmd.com/news/295034/

相关文章:

  • 2026.1.24 作业 - # P13521 [KOI 2025 #2] 包
  • 国产PCB阻抗测试分析仪:Bamtone班通怎么样?
  • 降AIGC率网站排名榜单:10大热门平台及免费付费功能对比
  • 【毕业设计】基于springboot的智能药箱系统(源码+文档+远程调试,全bao定制等)
  • YOLO26改进 - SPPF模块 | AIFI基于注意力的尺度内特征交互:替代SPPF构建高效混合编码器,提升模型综合效能
  • 2026.1.24 作业 - # P1362 兔子数
  • YOLO26改进 - SPPF模块 | 替代SPPF,FFocal Modulation焦点调制:即插即用轻量设计优化全局语义捕获
  • 大模型微调技术详解:从LoRA到P-Tuning v2,一文掌握高效微调方法
  • 用通俗的方式介绍大语言模型训练过程,非常详细收藏我这一篇就够了
  • 程序员收藏!AI产品经理转型与大模型学习全攻略,抢占AI时代先机,传统PM如何快速转型成AI产品经理?
  • 大模型训练全攻略:从监督学习到数据预处理的完整指南
  • 字节序及IP地址转换
  • LeetCode 134. 加油站(O(n)时间+O(1)空间最优解)
  • 【计算机毕业设计案例】基于Springboot的幼儿园综合管理系统基于springboot的幼儿园管理系统基于SpringBoot+Vue的幼儿园管理系统(程序+文档+讲解+定制)
  • 提示工程架构设计实战:旅游行业智能推荐提示系统架构设计全流程
  • 【计算机毕业设计案例】基于Java的养老院管理系统的设计与实现基于springboot的养老院管理系统的设计与实现(程序+文档+讲解+定制)
  • 深度学习篇---初看transformer
  • 固高控制板卡驱动安装教程
  • 基于大数据的图书推荐系统的设计与实现-计算机毕业设计源码+LW文档
  • 学术研究的第一步不再困难,AI工具助你轻松优化开题报告模板内容
  • 想要高效完成学术写作?这份AI辅助的开题报告模板是你的最佳选择
  • Java毕设选题推荐:基于springboot的幼儿园管理系统基于springboot的实验幼儿园信息管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 区间并查集|树状数组
  • 计算机Java毕设实战-基于springboot的幼儿园管理系统基于Springboot的幼儿园综合管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 【课程设计/毕业设计】基于springboot+vue的实验幼儿园信息管理系统基于springboot的幼儿园管理系统【附源码、数据库、万字文档】
  • Java计算机毕设之基于SpringBoot+Vue的幼儿园管理系统基于springboot的幼儿园管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • Expo+React Native实现鉴权
  • Java毕设项目推荐-基于springboot的养老院管理系统的设计与实现基于SpringBoot+Vue的养老院管理系统【附源码+文档,调试定制服务】
  • Java毕设项目推荐-基于Springboot的幼儿园综合管理系统基于springboot的幼儿园管理系统【附源码+文档,调试定制服务】
  • 随笔-无具体内容