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

[HEOI2016/TJOI2016] 排序 题解

[HEOI2016/TJOI2016] 排序 题解

很久没写过题解了,但这题思路十分新奇,震惊到我,并且让我学到了许多东西,故写篇题解纪念下。

洛谷题目传送门

题意

给定一个长度为 \(n\le 10^5\) 的序列。

\(m\le 10^5\) 次操作,每次给定一个区间,将区间内的数字排序,有升序降序两种。

问最后下标为 \(q\) 的数字的值。

思路

非常有意思,非常新奇。

01序列的排序

众所周知,对于一个长度为 \(n\) 的序列,排序的时间复杂度是 \(O(n\log n)\) 的。

但是对于一个 \(01\) 序列,甚至连 \(O(n)\) 都不需要,仅需个 \(O(\log n)\)

方法:

首先排序后的序列是有序的,必然是一段 \(0/1\) 连着第二段 \(0/1\)

那么就可以用线段树。

\(sum1\) 表示区间 \([l,r]\) 内的 \(1\) 的个数。

那么从大到小排序就是覆盖 \([l,l+sum1-1]\)\(1\)\([l+sum1,r]\)\(0\)

同理,从小到大就是覆盖 \([r-sum1+1,r]\)\(1\)\([l,r-sum1]\)\(0\)

然后我们就做到了针对 \(01\) 序列的 \(O(\log n)\) 排序。

题目转化

此时我们就尽量把原序列转化为 \(01\) 序列。

分析复杂度:

\(O(m\log n)\) 的操作是免不了的,剩下的最多再加上一只 \(\log\)

考虑二分答案。

将序列与我们二分出的 mid 进行比较,小于则变成 \(0\),否则是 \(1\)

那么我们 \(O(m\log n)\) 操作后,如果 \(q\) 位上是 \(1\),则代表 mid 小等于答案,否则大于。

二分判断的说明

其实如果我们在 \(m\) 次操作后再进行一次排序,可以发现答案的下标一定是在 \(0\) 段和 \(1\) 段的交汇点。

然而因为我们取 mid 时是按照大等于,所以答案的下标上的值一定是 \(1\)

然后我们就可以二分 check,总时间复杂度是 \(O(m\log^2n)\)

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ljl;
#define FUP(i,x,y) for(auto i=(x);i<=(y);++i)
#define FDW(i,x,y) for(auto i=(x);i>=(y);--i)
inline void Rd(auto &num);
const int N=1e5+5;
int n,m,a[N],q,t[N];
struct OPT{int op,l,r;
}opt[N];
namespace SMT{#define lc (p<<1)#define rc (p<<1|1)struct NODE{int l,r,sum,lz;}node[N*4];void pushup(int p){node[p].sum=node[lc].sum+node[rc].sum;return;}void bld(int l,int r,int p){node[p].l=l;node[p].r=r;node[p].lz=-1;if(l==r){node[p].sum=t[l];return;}int mid=(l+r)/2;bld(l,mid,lc);bld(mid+1,r,rc);pushup(p);return;}void pushdown(int p){if(node[p].lz==-1||node[p].l==node[p].r)return;node[lc].lz=node[p].lz;node[lc].sum=(node[lc].r-node[lc].l+1)*node[p].lz;node[rc].lz=node[p].lz;node[rc].sum=(node[rc].r-node[rc].l+1)*node[p].lz;node[p].lz=-1;return;}void addlr(int l,int r,int val,int p){if(l>r)return;pushdown(p);if(l<=node[p].l&&node[p].r<=r){node[p].lz=val;node[p].sum=(node[p].r-node[p].l+1)*val;return;}int mid=(node[p].l+node[p].r)/2;if(l<=mid)addlr(l,r,val,lc);if(mid<r)addlr(l,r,val,rc);pushup(p);return;}int query(int l,int r,int p){if(l>r)return 0;pushdown(p);if(l<=node[p].l&&node[p].r<=r)return node[p].sum;int mid=(node[p].l+node[p].r)/2,ans=0;if(l<=mid)ans+=query(l,r,lc);if(mid<r)ans+=query(l,r,rc);return ans;}
}
using namespace SMT;
bool check(int x)
{FUP(i,1,n)t[i]=(a[i]<x?0:1);bld(1,n,1);FUP(i,1,m){int l=opt[i].l,r=opt[i].r,op=opt[i].op;int sum1=query(l,r,1);if(op)//>{addlr(l,l+sum1-1,1,1);addlr(l+sum1,r,0,1);}else//<{addlr(r-sum1+1,r,1,1);addlr(l,r-sum1,0,1);}}return query(q,q,1);
}
int main(){Rd(n);Rd(m);FUP(i,1,n)Rd(a[i]);FUP(i,1,m){Rd(opt[i].op);Rd(opt[i].l);Rd(opt[i].r);}Rd(q);int l=1,r=n,mid,ans=0;/*遇到可能check(mid) ? l=mid的情况就用这种写法吧qwq */while(l<=r){mid=(l+r)/2;if(check(mid))ans=mid,l=mid+1;else r=mid-1;}printf("%d\n",ans);return 0;
}
inline void Rd(auto &num)
{num=0;char ch=getchar();bool f=0;while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}while(ch>='0'&&ch<='9'){num=(num<<1)+(num<<3)+(ch-'0');ch=getchar();}if(f)num=-num;return;
}

总结

这题真的让我学到了好多,所以特此记录思想。

http://www.jsqmd.com/news/167786/

相关文章:

  • B4450 [GESP202512 三级] 小杨的智慧购物
  • STLink驱动下载入门必看:新手快速上手指南
  • 10款降AI率工具盘点(含最新免费可用版~)
  • 233魔方、圆柱233A
  • 计算机Java毕设实战-基于Springboot的在线订餐系统设计与实现基于SpringBoot框架的线上订餐管理系统的设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • Java毕设项目:基于SpringBoot少数民族服饰在线销售系统的设计与实现(源码+文档,讲解、调试运行,定制等)
  • AI原生应用领域的思维树:未来发展趋势
  • 数学物理方程知识点总结
  • Python安装依赖超时?Miniconda-Python3.10启用国内镜像源
  • 161_尚硅谷_切片的课堂练习
  • 【课程设计/毕业设计】基于SpringBoot的在线服装商城销售系统基于SpringBoot少数民族服饰在线销售系统的设计与实现【附源码、数据库、万字文档】
  • 【课程设计/毕业设计】基于SpringBoot的订餐系统设计与实现基于SpringBoot框架的线上订餐管理系统的设计与实现【附源码、数据库、万字文档】
  • AI原生应用中对话状态跟踪的模型评估与选择
  • 【毕业设计】基于SpringBoot少数民族服饰在线销售系统的设计与实现(源码+文档+远程调试,全bao定制等)
  • 实测10款降AI率工具:论文AIGC痕迹太重?帮你免费降低AI率,还有免费ai查重!
  • Java计算机毕设之基于SpringBoot框架的线上订餐管理系统的设计与实现基于Spring Boot的网上订餐系统设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • Java毕设选题推荐:基于SpringBoot的民宿管理系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 这些近视防控坑别踩!从细节到方案,一篇讲透
  • 【课程设计/毕业设计】基于SpringBoot的民宿管理系统的设计与实现【附源码、数据库、万字文档】
  • Java毕设选题推荐:基于SpringBoot少数民族服饰在线销售系统的设计与实现基于springboot+vue的少数民族服饰与文化系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 试试2个免费工具!亲测10款免费降ai率工具推荐(2025年12月最新版)
  • Java毕设选题推荐:基于Spring Boot的网上订餐系统设计与实现基于SpringBoot框架的线上订餐管理系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • AI率降低到5%以下!亲测10款免费降ai率工具推荐(2025年12月最新版)
  • 【论文精读(十六)】Point Transformer V2:分组向量注意力(GVA)与位置编码的精妙权衡(NeurIPS 2022)
  • AI 不想取代播客主播,因为播客根本不赚钱|编码人声
  • 论文AIGC痕迹太重?亲测10款免费降ai率工具推荐(2025年12月最新版)
  • 还在用DeepSeek写论文?这7款免费AI工具,用真实文献帮你把AIGC率压到12%!
  • 【论文精读(十七)】Point Transformer V3:点云序列化(Serialization)与FlashAttention的效率革命(CVPR 2024)
  • 基于SpringBoot + Vue的个性化音乐推荐系统
  • 基于SpringBoot + Vue的个性化音乐推荐系统