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

相关文章:

  • 今天不建Lovable ML平台,明天就被团队弃用!2025年AI工程团队留存率预警下的4步速建法
  • AI浪潮下,软件开发行业的深度变革与未来走向
  • 深夜办公不掉链:2026免费PDF转PPT工具Top榜 - 时讯资讯
  • 投影仪的分辨率不高,仅为1024*768的分辨率,而笔记本电脑2560×1600(2.5K)分辨率。‌‌——如果采用扩展屏复制笔记本电脑分辨率,发现那个投影仪投影出的字很小,且看不清。 将笔记本电脑的
  • DriverStore Explorer终极指南:Windows驱动清理与管理的完整解决方案
  • 龙芯3A5000工业主板实战:从硬件部署到软件生态的国产化替代指南
  • 给机器人一个值得信赖的“判断力”
  • 79元工业级核心板实战:全志T113-i在PLC、HMI与网关中的应用与开发
  • 2026年PDF转PPT免费工具推荐:在线极速转换,省心又高效 - 时讯资讯
  • ESP-Mesh-Lite:基于Wi-Fi的轻量级Mesh组网方案解析与实践
  • Vue2进阶 - Ref
  • 独立开发者如何借助 Taotoken 控制个人 AI 项目开发成本
  • Jetson Nano上OpenCV C++ DNN人脸检测:CUDA加速全流程实战
  • C++跨平台线程池组件设计:从核心原理到工程实践
  • MPC5604B/C Memory Map 内存映射全解析
  • ARM架构下Cache原理与软件控制:从硬件黑盒到性能优化实战
  • 【燃烧机】模拟了燃烧机的热力学循环分析活塞动力学以及温度和压力变化对发动机效率的影响【含Matlab源码 15557期】
  • NBK_RD8x3x MCU开发实战:从GPIO到定时器中断实现LED精准闪烁
  • 车载音响升级指南:AE1-L方案核心解析与DSP调音实战
  • 基于Purple Pi OH的OpenHarmony标准系统7天实战入门指南
  • 中之网科技:让工业制造“被看见、被看懂”的三维可视化专家
  • C++学习之线程详解
  • 联发科MT6833与MT6853 5G核心板:规格对比与产品选型实战指南
  • 西恩士液冷板清洁度检测设备/检测仪/分析系统,全链路一站式解决 - 工业设备研究社
  • CM1-DAY1题目总结
  • STM32H5安全连接AWS IoT:基于TrustZone与Secure Manager的物联网方案
  • C/C++中#define与typedef的本质区别:从编译原理到工程实践
  • AI Agent如何重构课堂?揭秘2024年全球87所试点校的3个颠覆性教学范式
  • Purple Pi OH开发板7天实战OpenHarmony:从环境搭建到应用开发
  • 2026年使用降AI工具合法性深度解读:降AI到底是不是学术不端免费完整解析