当前位置: 首页 > 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.jsqmd.com/news/37817/

相关文章:

  • SOS DP
  • docker - 1 安装
  • 11月10日
  • 最小二乘困难详解5:非线性最小二乘求解实例
  • ##题解##洛谷P1578##最大子矩形 扫描线法
  • 【Azure Developer】azd 安装最新版无法登录中国区问题二:本地Windows环境遇问题
  • 密码校验函数
  • 英语_阅读_The progress of technology_待读
  • Mac 下载 VMware 11.1.0-1.dmg 后如何安装?超简单教程(附安装包)
  • 机动车登记证识别技术如何通过深度学习实现泛化能力提升
  • 在R中生成交互地图leaflet包
  • 深入解析:51单片机基础-矩阵按键
  • gmssl 国密标准下载
  • 没有路由器的情况下如何通过电脑网口连接开发板
  • 重练算法(代码随想录版) day 7 -哈希表part2
  • 团队作业2——《需求规格说明书》
  • gmssl常用命令 - 需要持续更新
  • 实用指南:根据用户行为数据中的判断列表在 Elasticsearch 中训练 LTR 模型
  • 转转客服IM聊天系统背后的技术挑战和实践分享
  • 英语_阅读_Computers_待读
  • 202511.11 - A
  • AT_arc160_c [ARC160C] Power Up
  • 英语_阅读_Life in cities_待读
  • 实验 5:ViT Swin Transformer
  • 一个强大的排序工具
  • 数据采集_2
  • chatTTS源码版本地部署踩的坑
  • 第一讲机器学习基础
  • Linux服务器编程实践20-TCP服务 vs UDP服务:核心差异对比 - 详解
  • 第二十八天