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

题解 P13524 [KOI 2025 #2] 跳跃

Solution

考虑已知一个排列 \(p\) 怎么推出 \(c\),显然是维护差分标记 \(t\),对于 \(p_i,p_{i+1}\),给 \(t_{\min(p_i,p_{i+1})}\gets t_{\min(p_i,p_{i+1})}+1\) 以及 \(t_{\max(p_i,p_{i+1})}\gets t_{\max(p_i,p_{i+1})}-1\)

显然可以从 \(c\) 简单推出 \(t\)。下面我们只讨论 \(i\in [2,n-1]\)。由于每个点只会被操作两次(到达一次,出发一次),则只可能存在 \(t_i\in \{-2,0,2\}\),且 \(\sum t_i=0\),即 \(-2\) 的个数 与 \(2\) 的个数相等。

考虑若 \(t_i=-2\),则两次操作这个点,\(i\) 都是作为终点,即 \(i\) 的左右两侧相邻的数都比 \(i\) 小;同理 \(t_i=2\) 表示两侧都比 \(i\) 大;\(t_i=0\) 表示一侧比 \(i\) 大,一侧比 \(i\) 小。

然后你会发现由于 \(c_i\) 为正,\(t_i\) 的每一个前缀和(从 \(2\) 开始)都是非负,所以第一个 \(2\) 一定在第一个 \(-2\) 之前,第二个 \(2\) 一定在第二个 \(-2\) 之前……然后就有一个很好的构造,把 \(1\) 放第一个,再放第一个 \(t_i=-2\)\(i\),放第一个 \(t_i=2\)\(i\),放第二个 \(t_i=-2\)\(i\),以此类推,不难发现一定满足要求。

什么?你问 \(t_i=0\) 怎么办?在任意两个数 \(p_i,p_{i+1}\) 之间插 \([p_i,p_{i+1}]\) 里面(或 \([p_{i+1},p_i]\) 里面)的数就行。随便用 set 搞一下即可。

代码里还缝了一个 checker。

Code

#include<bits/stdc++.h>
using namespace std;
namespace Z3k7223{const int N=2e5+10;int n;int ip[N],a[N];int ans[N],vis[N],tot;int tg_chk[N];void check1(){for(int i=1;i<n;i++){int x=ans[i],y=ans[i+1];if(x>y){swap(x,y);}++tg_chk[x],--tg_chk[y];}sort(ans+1,ans+1+n);for(int i=1;i<=n;i++){if(ans[i]!=i){cerr<<"NOT A PERMUTATION!\n";return;}}for(int i=1;i<n;i++){tg_chk[i]+=tg_chk[i-1];}int cnt=0;for(int i=1;i<n;i++){if(tg_chk[i]!=ip[i]){++cnt;}}cerr<<cnt<<" error(s) found\n";}int tag[N];set<int>s;void ins(int x){if(s.empty()){ans[++tot]=x;return;}vector<int>tmp;if(ans[tot]>x){auto it=s.lower_bound(ans[tot]);while(it!=s.begin()){--it;if(*it<x)break;ans[++tot]=*it;tmp.push_back(*it);}}else{auto it=s.lower_bound(ans[tot]);while(it!=s.end()){if(*it>x)break;ans[++tot]=*it;tmp.push_back(*it);++it;}}for(int r:tmp){s.erase(r);}ans[++tot]=x;}void main(){cin>>n;for(int i=1;i<n;i++){cin>>ip[i];}for(int i=1;i<=n;i++){a[i]=ip[i]-ip[i-1];ans[i]=i;if(a[i]==0){s.insert(i);}}vector<int>ar,br;for(int i=1;i<=n;i++){if(a[i]==-2){ar.push_back(i);}if(a[i]==2){br.push_back(i);}}ans[++tot]=1;for(int i=0;i<ar.size();i++){ins(ar[i]);ins(br[i]);}for(int i=1;i<=n;i++){cout<<ans[i]<<' ';}cout<<'\n';check1();}
}
int main(){Z3k7223::main();return 0;
}
http://www.gsyq.cn/news/46791.html

相关文章:

  • SOS DP
  • 11月10日
  • 密码校验函数
  • 没有路由器的情况下如何通过电脑网口连接开发板
  • AT_arc160_c [ARC160C] Power Up
  • 英语_阅读_Life in cities_待读
  • 一个强大的排序工具
  • 关于IP、TCP、UDP的校验和计算
  • 元叙事提示注入:突破AI安全边界的攻击技术
  • 【计算机网络表格图表解析】网络体系结构、资料链路层、网络层、传输层、应用层、网络安全、故障排查
  • ONES 重磅升级|全新内核,深度可配置,适配复杂业务流
  • CUDA安装注意事项
  • 102302145 黄加鸿 数据采集与融合技术作业2
  • 2025-11-11 早报新闻
  • K8S(九)—— Kubernetes持久化存储深度解析:从Volume到PV/PVC与StorageClass动态存储 - 教程
  • GPIO 也是一个接口,还有 QEMU GPIODEV 和 GUSE - 指南
  • Air780EPM系列低功耗模组USB设计进阶:硬件要点与LuatOS API开发赋能
  • 如何项目管理软件中计算预算?
  • 实用指南:【Qt】9.信号和槽_信号和槽存在的意义
  • DI依赖注入
  • 解码LVGL定时器
  • 如何选择锡林郭勒西林瓶灌装旋盖机?环境温湿度要求详解
  • 北京GEO优化服务商2025权威推荐:抢占AI搜索流量新入口
  • 雅思报班哪个机构比较好?过来人分享选择经验与价格课程对比
  • 云原生周刊丨runc 三大高危漏洞曝光
  • 【ACM出版 | EI检索稳定】2025年人工智能、业务转型和数据科学创新国际学术会议(ICBTDS 2025)
  • echarts 树形结构图实例
  • 国标GB28181算法算力平台EasyGBS:深度解析全场景视频调阅功能与行业实战应用
  • 2025出国留学机构综合实力榜:排名前十的留学中介特色分析
  • 基于SpringBoot+Vue的个人理财系统管理系统设计与建立【Java+MySQL+MyBatis完整源码】