SS241115C. 排序(sort)

news/2024/11/15 19:38:04/文章来源:https://www.cnblogs.com/liyixin0514/p/18547957

SS241115C. 排序(sort)

题意

给你一个长度为 \(n\) 的序列 \(a\),每次操作对 \([1,\frac{n}{2}],[\frac{n}{2}+1,n]\) 进行归并排序。有 \(q\) 次询问,给出 \(t,x\),问进行 \(t\) 次操作后 \(a_x\) 的值。

思路

考虑一次操作发生了什么。

假设 \(x<y\),那么 \(x\) 和它后面的一坨都会排到 \(y\) 前面。

这启发我们把左右两个序列分成若干区间,满足每个区间的开头都比后面那一坨大,比下一个区间开头小。

把一个区间看做一个关于开头的整体,一次操作就是给这些区间排序,区间内部不变。

进行一次操作后,如果有一个块横跨了左右不分,就把这个块拆开,\(\le \frac{n}{2}\) 的为一部分,右边拆成若干块。

这个拆块的操作我们只会做 \(O(n)\) 次,因为拆完就不会合并回去了。

可以使用权值线段树维护。线段树下标表示开头的值,每次线段树二分找出横跨的块,如果没有那么排序就结束了,否则拆块,更新线段树。

因为拆块 \(O(n)\) 次,因此其实排序的操作最多也是 \(O(n)\) 次。

需要预处理每个位置后面第一个比它大的位置,这样才能保证拆一次块时间是 \(O(1)\) 的。

总时间复杂度 \(O(n \log n)\)

code

#include<bits/stdc++.h>
#define sf scanf
#define pf printf
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
using namespace std;
typedef long long ll;
namespace struggle {#define isdigit(x) (x>='0'&&x<='9')#define gc getchar_unlocked#define pc putchar_unlockedtemplate <typename T>void read(T &x) {x=0;char ch=gc();for(;!isdigit(ch);ch=gc()) ;for(;isdigit(ch);ch=gc()) x=(x<<3)+(x<<1)+(ch^48);}template <typename T>void write(T x,char ch) {static int st[40];int top=0;do {st[top++]=x%10;x/=10;}while(x);while(top) pc(st[--top]^48);pc(ch);}constexpr int N=2e5+7,M=1e6+7;int n,q,t;int a[N];int c[N];int x;struct node {int id,t,x;}b[M];bool cmp (node a,node b) { return a.t < b.t; }int ne[N];int que[N],r;int _upper_bound(int x) {if(a[que[1]]<x) return n+1;int L=1,R=r;while(L<R) {int mid=(L+R+1)>>1;if(a[que[mid]]>x) L=mid;else R=mid-1;}return que[L];}int ans[M];struct segtree {int tr[N<<2];void pushup(int u) { tr[u]=tr[u<<1]+tr[u<<1|1]; }void insert(int u,int l,int r,int x,int w) {if(l==r) {return tr[u]+=w, void(0);}int mid=(l+r)>>1;if(x<=mid) insert(u<<1,l,mid,x,w);else insert(u<<1|1,mid+1,r,x,w);pushup(u);}bool chai(int u,int l,int r,int k) {if(l==r) {if(tr[u]==k) return 0;int len=tr[u]-k;tr[u]=k;int y=c[l]+k;while(len) {int p=min(len,ne[y]-y); insert(1,1,n,a[y],p);len-=p;y+=p;}return 1;}int mid=(l+r)>>1;bool ans=0;if(tr[u<<1]>=k) ans=chai(u<<1,l,mid,k);else ans=chai(u<<1|1,mid+1,r,k-tr[u<<1]);pushup(u);return ans;}int query(int u,int l,int r,int x) {if(l==r) {int p=c[l]+x-1;return a[p];}int mid=(l+r)>>1;if(tr[u<<1]>=x) return query(u<<1,l,mid,x);return query(u<<1|1,mid+1,r,x-tr[u<<1]);}}T;void main() {read(n),read(q);rep(i,1,n) read(a[i]), c[a[i]]=i;rep(i,1,q) {read(t),read(x);b[i]={i,t-1,x};}sort(b+1,b+q+1,cmp);per(i,n,1) {ne[i]=_upper_bound(a[i]);while(r&&a[que[r]]<a[i]) --r;que[++r]=i;}int k=1;while(k<=(n>>1)) {int p=min(ne[k],(n>>1)+1);T.insert(1,1,n,a[k],p-k);k=p;}while(k<=n) {int p=ne[k];T.insert(1,1,n,a[k],p-k);k=p;}int cnt=0;int m=0;while(m<q&&b[m+1].t==-1) ++m, ans[b[m].id]=a[b[m].x];while(m<q&&b[m+1].t==0) ++m, ans[b[m].id]=T.query(1,1,n,b[m].x);while(m<q) {++cnt;if(!T.chai(1,1,n,n>>1)) {while(m<q) {++m;ans[b[m].id]=T.query(1,1,n,b[m].x);}break;}while(b[m+1].t==cnt) ++m, ans[b[m].id]=T.query(1,1,n,b[m].x);}rep(i,1,q) write(ans[i],'\n');}
}
int main() {#ifdef LOCALfreopen("my.out","w",stdout);#else freopen("sort.in","r",stdin);freopen("sort.out","w",stdout);#endifstruggle :: main();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/834201.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

生产环境中AI调用的优化:AI网关高价值应用实践

随着越来越多的组织将生成式AI引入生产环境,他们面临的挑战已经超出了初步实施的范畴。如果管理不当,扩展性限制、安全漏洞和性能瓶颈可能会阻碍AI应用的推广。实际问题如用户数据的安全性、固定容量限制、成本管理和延迟优化等,需要创新的解决方案。 本文我们深入探讨了一些…

MobileViT-v1-所有patch内相对位置相同的token之间计算自注意力

paper def my_self(x: torch.Tensor):通过这段代码 可以把每张图片图片中相对位置相同的若干个tokens放到最后两个维度# [B, C, H, W] -> [B, C, n_h, p_h, n_w, p_w] # n_h是高度方向上可以分多少个patch p_h patch的高度 n_w 宽度方向上可以分多少个patch p_w patch的宽…

27. 使用MySQL之全球化和本地化

1. 字符集和校对顺序 数据库表被用来存储和检索数据。不同的语言和字符集需要以不同的方式存储和检索。因此,MySQL需要适应不同的字符集(不同的字母和字符),适应不同的排序和检索数据的方法。 在讨论多种语言和字符集时,将会遇到以下重要术语:字符集为字母和符号的集合;…

TCP/IP上三层协议

TCP/IP上三层的角色 同一台设备上的进程间通信有多种方式,如管道、消息队列、共享内存、信号等。而不同设备间的进程通信需要网络通信,由于设备具有多样性,因此协商出了一套通用的网络协议。这个网络协议是分层的,每一层都有各自的作用和职责,接下来将依据 “TCP/IP 网络模…

无线部分

AC堆叠(VAC) 配置两台AC设备,使用虚拟化方案组合成1台虚拟AC。 AC1和AC2之间的G 0/3-4端口作为虚拟交换链路。配置AC1为主,AC2为备。主设备 description为AC1,备用设备description为AC2。 AC1 virtual-ac domain 100device 1 device 1 priority 200 device 1 description …

DHCP欺骗

DHCP 欺骗原理DHCP 协议(Dynamic Host Configuration Protocol) 动态主机配置协议:主要给客户机提供 TCP/IP 参数,包括:IP 地址、子网掩码、网关、DNS、租期工作原理应用层协议,基于UDP 主机向服务器 67 号端口发送 DHCP 请求 服务器响应给客户机的 68号端口配置设置DHCP 服…

Redis运行的时候碰到# Creating Server TCP listening socket *:6379: bind: No error

Redis运行的时候碰到# Creating Server TCP listening socket *:6379: bind: No error 解决方案: 1、启动redis客户端:redis-cli.exe。 2、执行关闭命令:输入shutdown3、执行退出命令:exit4、重新启动Redis输入:redis-server.exe redis.windows.conf

https实验

https 实验原理httphttps https = http + SSL/TLS •SSL: Secure Socket Layer 安全套接层 •TLS: Transport Layer Security 传输层安全协议加密方式:PKI(公钥基础设施)使用公钥技术和数字签名来保证信息安全由公钥密码算法、数字证书(Certificate)、CA(Certificate Aut…

手把手教你搭建OpenScenario交通场景(上)

经纬恒润动力学仿真软件ModelBase基于OpenScenario1.0标准,开发内嵌了场景编辑器,可用于对仿真测试过程中的车辆行驶道路模型之外,继续进行周边动态场景的搭建。 OpenScenario是一种专为自动驾驶系统仿真测试设计的场景描述语言,它基于XML格式,旨在提供一个标准化、…

动态规划题单2

第一个题单编辑到后面实在是太卡了,就新开了一个,以后应该也会 \(30\) 题为一个题单。 31.CF1580D Subsequence CF1580D Subsequence 不会笛卡尔树,但是看到题解区的妙妙解法...... 题目的式子非常大便,我们考虑把它翻译成人话: 一个子序列的价值为: \(sum*m - 每两个数及他…

java 反序列化 cc7 复现

java 反序列化 cc7 复现复现环境:common-collections版本<=3.2.1,java版本随意.cc7就是cc6换了一个出口,整体的逻辑没有太大的变化.在Lazymap之前的还那样,我们从如何触发Lazymap的get方法开始看起. AbstractMap 看他的equals方法 public boolean equals(Object o) { if (o…

告别Print,使用IceCream进行高效的Python调试

在Python开发实践中,调试是一个不可或缺的环节。如果采用print()语句来追踪程序执行流程,可能会遇到一个持续出现的异常情况,并且经过多次代码审查问题的根源仍然难以确定,这可能是因为随着终端输出信息的不断增加,这种调试方式的局限性逐渐显现。本文将介绍IceCream库,这…