Atcoder ABC392F Insert 题解 [ 绿 ] [ 线段树二分 ] [ 倒序操作 ]
Insert:绷不住了,ds 学傻了导致一直在写一个假的没边的做法,赛后 5min 胡出正解,唐。
思路
首先正着操作想想就觉得不太好搞,所以考虑一个经典 trick:单点正向加入操作转化为倒序删除操作。
于是插入就变成了删除,那么继续考虑删除一个数意味着啥,意味着最终后面的数在当前的操作下位置全部减 \(1\) 了。那么这个删除的数要不要管呢?显然是不要的,我们查询的时候可以查询最后一个值为 \(x\) 的下标,这样就可以自动忽略删除了的数。
这个过程可以用线段树实现,维护最终答案下每个位置对应当前操作下的位置下标,每次在线段树上二分得到最后一个值为 \(x\) 的下标 \(k\) 后,对区间 \([k+1,n]\) 进行减 \(1\) 操作即可。
时间复杂度 \(O(n\log n)\)。
后来发现这个东西可以直接权值线段树维护每个位置是否删除,然后查询排名为 \(p\) 的点即可,不过我只写了上面那个普通线段树的做法。
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
using pl=pair<ll,int>;
const int N=500005;
int n,p[N],a[N],ans[N];
struct Node{
int l,r;
int mn,tag=0;
};
struct Segtree{
Node tr[4*N];
void pushup(int p)
{
tr[p].mn=min(tr[lc].mn,tr[rc].mn);
}
void pushdown(int p)
{
if(tr[p].tag)
{
tr[lc].tag+=tr[p].tag;
tr[rc].tag+=tr[p].tag;
tr[lc].mn+=tr[p].tag;
tr[rc].mn+=tr[p].tag;
}
tr[p].tag=0;
}
void build(int p,int ln,int rn)
{
tr[p]={ln,rn,a[ln],0};
if(ln==rn)return;
int mid=(ln+rn)>>1;
build(lc,ln,mid);
build(rc,mid+1,rn);
pushup(p);
}
void update(int p,int ln,int rn)
{
if(ln<=tr[p].l&&tr[p].r<=rn){tr[p].tag-=1;tr[p].mn-=1;return;}
pushdown(p);
int mid=(tr[p].l+tr[p].r)>>1;
if(ln<=mid)update(lc,ln,rn);
if(rn>=mid)update(rc,ln,rn);
pushup(p);
}
int query(int p,int x)
{
if(tr[p].l==tr[p].r)return tr[p].l;
pushdown(p);
int mid=(tr[p].l+tr[p].r)>>1;
if(tr[rc].mn<=x)return query(rc,x);
return query(lc,x);
}
}tr1;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>p[i];
for(int i=1;i<=n;i++)a[i]=i;
tr1.build(1,1,n);
for(int i=n;i>=1;i--)
{
int x=tr1.query(1,p[i]);ans[x]=i;
if(x+1<=n)tr1.update(1,x+1,n);
}
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
return 0;
}
Atcoder ABC392F Insert 题解 [ 绿 ] [ 线段树二分 ] [ 倒序操作 ]的更多相关文章
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- hdu4614 线段树+二分 插花
Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- 【洛谷P2894】Hotel 线段树+二分查询
题目大意:给定一个长度为 N 的序列,每个点有两种状态 1/0,表示占有和空闲,现支持 first-fit 查询是否有一段连续的长度为 X 的空闲子序列和区间赋值操作. 题解:get到了线段树新技能. ...
- bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...
- [BZOJ 2653] middle(可持久化线段树+二分答案)
[BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...
- Color the ball(树状数组+线段树+二分)
Color the ball Time Limit : 9000/3000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Tota ...
- luogu4422 [COCI2017-2018#1] Deda[线段树二分]
讨论帖:线段树二分的题..我还考场切过..白学 这题我一年前的模拟赛考场还切过,现在就不会了..好菜啊. 显然直接线段树拆成$\log n$个区间,然后每个区间在进行线段树二分即可. UPD:复杂度分 ...
- Educational Codeforces Round 64 (Rated for Div. 2) (线段树二分)
题目:http://codeforces.com/contest/1156/problem/E 题意:给你1-n n个数,然后求有多少个区间[l,r] 满足 a[l]+a[r]=max([l, ...
随机推荐
- vue3 + pnpm 打造一个 monorepo 项目
Monorepo 和 Multirepo 单一仓库(Monorepo)架构,可以理解为:利用单一仓库来管理多个packages的一种策略或手段:与其相对的是多仓库(Multirepo)架构 Monor ...
- To B企业:2025继续打价格战,只有死路一条
从双十一数不清的促销.满减还有消费券,到大模型厂商的"你低价,我免费"中可以窥见,最近几年,在产品泛滥.市场红利消失的困境中,"价格战"已从To C卷到To B ...
- 技术实践|Redis基础知识及集群搭建(上)
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.本篇文章围绕Redis基础知识及集群搭建相关内容进行了分享 ...
- gradle 很棒
一直以为 gradle 就是 maven 的一个易读版,表达上比 XML 更精简了,实际上还是maven,似乎没有存在的必要. 但是,万万没想到,这玩意儿竟然是一个语言,竟然可以调试!也就是说,它不是 ...
- 刷到一个 MLSQL 语言
在 https://www.infoq.cn/video/2vFUBYfxFcoFWmSm5WOj 刷到一个 MLSQL 语言,主页 https://www.mlsql.tech/home ,意思是用 ...
- 【数据结构】【直接排序法】Java代码
public class 直接排序 { /** * 直接排序法 仅排序1轮 * @param arr 数组 * @param ji 基准索引,填写几,就以谁为基准进行一次划分 */ public st ...
- 【前端】白天/黑夜主题切换:JS读取XML预设主题实现黑白主题切换
上扩展实现多主题选择,切换主题) 先看一下XML文档 id值不能重复,一套主题的name要相同,亮色type1,暗色type0 <?xml version="1.0" enc ...
- 爬虫自动化脚本+AI赋能
简介 估计大家对网页爬取和数据抓取已经有所了解,市面上也有许多现成的软件可供使用.例如,前几天群里有位朋友利用爬虫技术抓取了AV网站,并搭建了一个磁力链接站点. 本文将介绍如何模拟手动操作,将一些繁琐 ...
- Qt数据库应用14-超级自定义委托
一.前言 在QTableView.QTreeView以及对于衍生的QTableWidget.QTreeWidget类中,需要用到自定义委托的情形很多,比如提供下拉框选择,进度条展示下载进度啥的,默认的 ...
- Qt编写安防视频监控系统27-GPU显示
一.前言 之前用ffmpeg解码的时候,已经做了硬解码的处理,比如支持qsv.dxva2.d3d11va等方式进行硬解码处理,但是当时解码出来以后,还是重新转成了QImage来绘制,这样就大打折扣了, ...