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

题解:luogu P8996([CEOI 2022] Abracadabra)

1. Description

Tin 是一位著名的魔术师,他的一个经典魔术与洗牌有关。

Tin 会准备一套牌,总共 \(n\) 张(保证 \(n\) 为偶数),各编号为 \(1\sim n\),一开始的时候牌是乱的且倒扣在桌子上。紧接着他开始表演洗牌,在洗牌的任意时刻,观众都可以向 Tin 询问从底往上数第 \(t\) 张牌是什么牌,很显然 Tin 一定会立即回答出正确答案。

事实上,Tin 采用如下方式来完成这个魔术,首先他记下了一开始的 \(n\) 张牌的顺序,接着采用如下技巧洗牌:

  1. 拿起自顶向下 \(\frac{n}{2}\) 张牌放在右手,自底向上 \(\frac{n}{2}\) 张牌放在左手,牌的正面对着桌子。
  2. 借助他的记忆,将左右手最底下的牌进行比较,将编号较小的那张牌放下,重复这个操作直到左右手一边为空。
  3. 将还有牌的那只手上的所有牌放下。

请你写一个程序模拟 Tin 的魔术。

2. Solution

首先需要观察。
不妨假设,Tin 左手上的 \(\frac{n}{2}\) 张牌的值为 \(\{a_i\}\),右手上的 \(\frac{n}{2}\) 张牌的值为 \(\{b_i\}\),此时左手过到第 \(i\) 张牌,右手过到第 \(j\) 张牌,且 \(a_i<b_j\)(反之同理)。
因为 \(a_i<b_j\),所以 \(a_i\) 后面一串小于 \(a_i\) 的值同样小于 \(b_j\),所以从 \(i\) 到下一张值比 \(a_i\) 大的牌之间的这一段都会被直接放下去。
这个观察启示我们,要将按照前缀最大值将整个序列分成若干段。
则一次操作相当于:将序列分成两份,然后将两段的前缀最大值排序。
进一步,我们可以想到,整个序列的前缀最大值本来就是有序的,不有序的地方只有在中间分开之后新产生的前缀最大值。
所以一次操作如下:我们找到跨过 \(\frac{n}{2}\) 这个位置的段,然后将它分成若干个新段再重新加入序列。
如何将一整段分成若干个新段?
不难想到,在 \(\frac{n}{2}\) 前的部分单独为一段,然后 \(\frac{n}{2}\) 后面的这一部分一定和原序列中的对应部分的序列是一样的,所以,我们在原序列上预处理出 \(nxt_i\) 表示 \(i\) 右边第一个比 \(i\) 大的位置,接着暴力跳 \(nxt_i\) 就可以了,很显然,每一个位置只会被跳一次,所以时间复杂度仍然正确。
同时,我们就可以证明,最多经过 \(n\) 次操作,整个序列就不会发生变化。原因是,如果某一次操作,没有产生新的前缀最大值,那么说明此时序列中不存在跨过 \(\frac{n}{2}\) 的段,所以序列一定不发生变化,否则,每一个位置,最多成为一次新增的前缀最大值,所以最多也只有 \(n\) 次操作。
用随便什么数据结构维护整个序列,就可以做到 \(O(n\log n)\) 的时间复杂度。
询问也很简单,在此不过多赘述。

3. Code

/*by ChenMuJiu*/
/*略去缺省源与快读快写*/
const int N=2e5+5,M=1e6+5;
int n,m,top;
int ans[M],c[N],pos[N],nxt[N],st[N];
vector<pii>b[N];
mt19937 ran(time(0));
struct Node{int val,len,dis;
};
struct Treap{int num,rt;int val[N<<1],len[N<<1],sum[N<<1],ch[N<<1][2];unsigned int c[N<<1];int New(int _val=0,int _len=0){int p=++num;val[p]=_val,len[p]=_len,sum[p]=_len;ch[p][0]=0,ch[p][1]=0;c[p]=ran();return p;}void pushup(int p){sum[p]=sum[ch[p][0]]+len[p]+sum[ch[p][1]];}pii split(int p,int v){if(!p)return {0,0};if(val[p]<=v){pii tmp=split(ch[p][1],v);ch[p][1]=tmp.first;pushup(p);return {p,tmp.second};}else{pii tmp=split(ch[p][0],v);ch[p][0]=tmp.second;pushup(p);return {tmp.first,p};}}int merge(int x,int y){if(x==0&&y==0)return 0;if(x==0)return y;if(y==0)return x;if(c[x]<c[y]){ch[x][1]=merge(ch[x][1],y);pushup(x);return x;}else{ch[y][0]=merge(x,ch[y][0]);pushup(y);return y;}}pii find(int p,int k){if(sum[ch[p][0]]>=k)return find(ch[p][0],k);k-=sum[ch[p][0]];if(len[p]>=k)return {k,p};k-=len[p];return find(ch[p][1],k);}void insert(int _val,int _len){int p=New(_val,_len);pii tmp=split(rt,_val-1);rt=merge(tmp.first,merge(p,tmp.second));}void erase(int _val){pii tmp1=split(rt,_val-1);pii tmp2=split(tmp1.second,_val);rt=merge(tmp1.first,tmp2.second);}Node query(int k){pii tmp=find(rt,k);return {val[tmp.second],len[tmp.second],tmp.first};}
}treap;
signed main(){read(n),read(m);for(int i=1;i<=n;i++)read(c[i]);for(int i=1,t,p;i<=m;i++){read(t),read(p);if(t==0){ans[i]=c[p];continue;}tomin(t,n);b[t].push_back({p,i});}st[0]=n+1;for(int i=n;i>=1;i--){pos[c[i]]=i;while(top&&c[st[top]]<c[i])top--;nxt[i]=st[top];st[++top]=i;}for(int i=1;i<=n;i=nxt[i])treap.insert(c[i],nxt[i]-i);for(int i=1;i<=n;i++){Node tmp=treap.query(n>>1);treap.erase(tmp.val);treap.insert(tmp.val,tmp.dis);int R=pos[tmp.val]+tmp.len-1;for(int j=pos[tmp.val]+tmp.dis;j<=R;j=nxt[j]){treap.insert(c[j],min(R+1,nxt[j])-j);}for(auto tmp:b[i]){Node res=treap.query(tmp.first);ans[tmp.second]=c[pos[res.val]+res.dis-1];}}for(int i=1;i<=m;i++)write(ans[i]),Nxt;
}
http://www.zskr.cn/news/1360028.html

相关文章:

  • agent memory论文解析一:解析项目(a-mem)
  • 机场应急处置保障:黎阳之光无感赋能,精准调度救援,提升处置能力
  • Python自动化办公:批量处理Word文档的实用技巧
  • 突破性升级:Windows Package Manager 1.8让软件管理效率提升300%
  • 全球AI范式变革与中国产业的破局路径
  • Vue大屏自适应组件v-scale-screen:解决企业级数据可视化适配难题
  • EdgeRemover:3步完成Microsoft Edge浏览器的高效卸载与重装指南
  • 开发智能体时,什么时候需要 RAG,什么时候不需要
  • 如何在Matlab中调用Taotoken聚合大模型API进行数据分析
  • 社媒运营做久了才会发现 真正让账号变强的往往不是爆款而是节奏一致性
  • 2026年PDF转PPT免费工具推荐:在线极速转换,省心又高效 - 时讯资讯
  • 洛雪音乐音源:打破音乐平台壁垒的聚合解决方案
  • 分布式系统开发实战:从核心原理到主流平台应用指南
  • Jetson Nano上OpenCV C++ DNN人脸检测:CUDA加速全流程实战
  • MySQL 8.0 新特性详解:从窗口函数到原子 DDL,这些功能你必须知道
  • VL53L8CX运动指示器实战:从原理到低功耗手势检测应用
  • RK3588开发环境搭建三步曲:从零构建嵌入式Linux编译与烧录系统
  • 西恩士液冷板清洁度检测设备/检测仪/分析系统,全链路一站式解决 - 工业设备研究社
  • 嵌入式离线地图导航:iMLite AI Map 2.1在智能穿戴设备中的实践
  • iOS 18.2深度体验:Siri融合ChatGPT、视觉智能与AIGC的AI交互革命
  • 基于gRPC反射的动态代理:无侵入实现HTTP/JSON与gRPC协议转换
  • 电机控制入门实战:从PWM调速到步进电机精准定位
  • 从NoHttpResponseException到线程泄漏:HttpClient配置不当引发的OOM事故复盘
  • CM1-DAY1题目总结
  • STM32MP1 M4内核定时器中断配置与调试实战
  • 基于RK平台的智慧出行方案:从芯片选型到车规级开发的实战指南
  • WzComparerR2终极指南:解锁冒险岛游戏数据的完整解决方案
  • 鱼骨图分析法
  • Pearcleaner:如何彻底清理Mac应用残留文件?免费开源工具完整指南
  • 【AI Agent行业落地实战指南】:2024年7大高价值场景×5类失败陷阱×3步快速验证法