简要题意

你需要维护一个长度为 \(L\) 的序列 \(a\),初始时全部都是 \(0\),有 \(N\) 个操作,支持:

  • C p x,将 \(a_p\) 修改为 \(x\)。
  • Q a b,输出 \([a,b]\) 中的第 \(8\) 大元素的值。

\(1 \leq L,N \leq 10^5\),对于任意时刻,存在 \(0 \leq a_i \leq 10^9\)。

思路

据说这道题有普通线段树的 \(O(N\log N)\) 做法,但我不会,下面介绍一种较为常规的 \(O(N\log^2 N)\) 做法。

首先,看到单点修改区间求第 \(k\) 大元素,你会想到什么。我相信大家的答案都是:树状数组套可持久化权值线段树。但是这玩意太难写,还容易写错。于是我们可以考虑离线算法——整体二分。

先来考虑一个静态版本,即没有修改,你会怎么做?按照常规思路,我们可以在遍历到询问区间 \([L,R]\),值域区间 \([l,r]\) 时。按照询问区间中小于等于 \((l+r)\div 2\) 数的多少分成分两拨,一波小于等于 \(k\)(此时答案小于等于 \((l+r)\div 2\))和大于。然后向下递归。注意查询数的多少可以使用树状数组优化。

如果有修改呢,同样我们应该也把它分成两拨。同样依照整体二分的“值域中点影响”思想,我们可以将修改的值按照 \((l+r)\div 2\) 分成两拨,这样答案就和值域重点有关了。

但是修改会有后效性,我们在处理询问的时候,上一个操作修改的值会影响到当前的操作。我们可以考虑维护两种询问,一种是擦除上一次修改,一种补上这一次修改。两个操作一起加入操作数组,由于顺序性,就可以出色的解决这个问题。

我们分析以下时间复杂度,假设 \(L,N\) 同阶。那么树状数组需要 \(\log N\),询问遍历所有区间 \(N\log N\)(参见调和级数的性质),整体时间复杂度 \(O(N\log^2 N)\)。

另外提一句,这道题是 P2617 Dynamic Rankings 的弱化版。

代码

没有卡常,截止至 \(\text{2022-11-25 12:43:35}\) 位于最优解第三(整体二分比树套树略微慢一点)。

#include <bits/stdc++.h>
#define int long long
using namespace std; int n,m;
const int N = 2e5+5;
int a[N];
namespace BIT{
#define lowbit(x) ((x)&(-(x)))
int t[N];
void update(int p,int v){
while(p<=n){
t[p]+=v;
p+=lowbit(p);
}
}
int query(int p){
int ans=0;
while(p){
ans+=t[p];
p-=lowbit(p);
}
return ans;
}
int query(int l,int r){
return query(r)-query(l-1);
}
} struct Query{
int op,l,r,k,p,v,id;
} q[N]; int ans[N]; void solve(int ql,int qr,int l,int r){
// cout<<ql<<' '<<qr<<' '<<l<<' '<<r<<'\n';
if(ql>qr||l>r){
return;
}
if(l==r){
for(int i=ql;i<=qr;i++){
if(q[i].op==1)ans[q[i].id]=l;
}
return;
}
int mid=(l+r)>>1;
vector<Query> q1,q2;
for(int i=ql;i<=qr;i++){
if(q[i].op==1){
int v=BIT::query(q[i].l,q[i].r);
if(q[i].k<=v){
q2.push_back(q[i]);
}
else{
q[i].k-=v;
q1.push_back(q[i]);
}
}
else{
if(q[i].v<=mid){
q1.push_back(q[i]);
}
else{
BIT::update(q[i].p,q[i].k);
q2.push_back(q[i]);
}
}
}
for(Query i : q2){
if(i.op!=1){
BIT::update(i.p,-i.k);
}
}
for(int i=0;i<(int)q1.size();i++){
q[ql+i]=q1[i];
}
for(int i=0;i<(int)q2.size();i++){
q[ql+q1.size()+i]=q2[i];
}
solve(ql,ql+q1.size()-1,l,mid);
solve(ql+q1.size(),qr,mid+1,r);
} signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>m;
int tot=0;
for(int i=1;i<=m;i++){
char op;int jr,ytxy;
cin>>op>>jr>>ytxy;
if(op=='C'){
if(a[jr]){
q[++tot].op=0;
q[tot].p=jr;
q[tot].v=a[jr];
q[tot].k=-1;
}
q[++tot].op=0;
q[tot].p=jr;
q[tot].v=ytxy;
q[tot].k=1;
a[jr]=ytxy;
}
else{
q[++tot].op=1;
q[tot].l=jr;
q[tot].r=ytxy;
q[tot].k=8;
q[tot].id=i;
}
}
for(int i=1;i<=m;i++)ans[i]=-114514;
solve(1,tot,0,1e9);
for(int i=1;i<=m;i++){
if(ans[i]>=0)cout<<ans[i]<<'\n';
}
return 0;
}

P8701 [蓝桥杯 2019 国 B] 第八大奇迹的更多相关文章

  1. 第十届蓝桥杯2019年C/C++ 大学A组省赛试题

    2019年蓝桥杯第十届软件类省赛 C/C++ 大 学 A 组 试题 A: 平方和 本题总分:5 分 [问题描述] 小明对数位中含有 2.0.1.9 的数字很感兴趣,在 1 到 40 中这样的数包括 1 ...

  2. 第十届蓝桥杯2019年C/C++ 大学B组省赛试题

    2019年第十届蓝桥杯大赛软件类省赛C/C++大学B组 试题 A:组队 本题总分:5分 [问题描述] 作为篮球队教练,你需要从以下名单中选出 1号位至 5号位各一名球员, 组成球队的首发阵容. 每位球 ...

  3. 今日学习——蓝桥杯 2019年 C语言 B组

    1.手淦(亲身体验,,,没啥大用,最终还是代码) 2.代码(下面是我看其他博主代码答案能看的懂的....具体的可以直接去下面的网址看) https://blog.csdn.net/qq_4452491 ...

  4. 蓝桥杯2019初赛]迷宫(dfs版本)

    传送门 大意: 题目的意思还是模板的搜索,不同的是我们要记录路径了,而且是最短字典序最小的路径. 思路: 1.对于字典序最小,也就是说我们要尽量先往下走,然后是左- 这个很简单,因为在dfs中是顺序枚 ...

  5. 平方十位数(蓝桥杯第八届国赛真题 JAVA-B组)

    思路:从大到小枚举,判断其平方是否不重复 答案:9814072356 //水题 标题:平方十位数 由0~9这10个数字不重复.不遗漏,可以组成很多10位数字. 这其中也有很多恰好是平方数(是某个数的平 ...

  6. 2019第十届蓝桥杯省赛及国赛个人总结(java-B组)

    省赛: 今年省赛的题目比18年简单的多,基本都是暴力枚举.BFS之类.还记得去年在山师考蓝桥杯,我这种辣鸡连题目都没看懂.本以为蓝桥会变得越来越难,没想到今年就被打脸了.今年省赛后面三个编程大题一个没 ...

  7. 2019年第十届蓝桥杯国赛总结(JavaA组)

    JavaA组国二,可以报销了~ JA死亡之组可不是盖的,rank12的排名还是拿不到国一啊(只有五个.. 出成绩的一刻波澜不惊,毕竟去年有国一了不慌哈哈哈 不过对我来说这个结果还算意料之外吧,毕竟大三 ...

  8. 2019年第十届蓝桥杯省赛总结(JavaA组)

    //update3.28:省一rank4,莫名进了国赛好神奇.. 记yzm10第一次体验A组(纯粹瞎水). 早闻山东的JavaA组神仙打架,进国赛都成了奢望(往年只有五个名额),因此抱着做分母的心态来 ...

  9. 记 2019蓝桥杯校内预选赛(JAVA组) 赛后总结

    引言 好像博客好久没更新了 哈哈哈哈哈 趁现在有空更新一波 不知道还有没有人看 确实该记录一下每天做了什么了 不然感觉有些浑浑噩噩了 比赛介绍 全称: 蓝桥杯全国软件和信息技术专业人才大赛 蓝桥杯 实 ...

  10. 蓝桥杯第十届真题B组(2019年)

    2019年第十届蓝桥杯大赛软件类省赛C/C++大学B组# 试题 A:组队# 本题总分:5分[问题描述]作为篮球队教练,你需要从以下名单中选出 1号位至 5号位各一名球员,组成球队的首发阵容.每位球员担 ...

随机推荐

  1. AT24C02

    AT24C02是一款拥有256bytes(32Page)的EEPROM. 一 :特点(部分) 1:双线接口: 2:双向数据传输协议: 3:400KHz波特率: 4:硬件写保护: 5:最大5ms写入同步 ...

  2. PaddleOCR-EAST

    目录 EAST Abstract Train PreProcess Architecture Backbone Neck Head Loss Dice Loss SmoothL1 Loss Infer ...

  3. 知识图谱顶会论文(ACL-2022) PKGC:预训练模型是否有利于KGC?可靠的评估和合理的方法

    PKGC:预训练模型是否有利于KGC?可靠的评估和合理的方法 论文地址:Do Pre-trained Models Benefit Knowledge Graph Completion? A Reli ...

  4. 乾象投资:基于JuiceFS 构建云上量化投研平台

    背景 乾象投资 Metabit Trading 成立于2018年,是一家以人工智能为核心的科技型量化投资公司.核心成员毕业于 Stanford.CMU.清北等高校.目前,管理规模已突破 30 亿元人民 ...

  5. python删除某一文件夹下的重复文件

    #2022-10-28 import hashlib import os import time def getmd5(filename): """ 获取文件 md5 码 ...

  6. JAVA语言学习-面向对象(1)

    类与对象 类 类是JAVA语言中重要的复合型数据类型().类的实现包括两个部分:成员变量和成员方法("方法"可以看作是C语言中的函数) 类的声明 要使用类,首先得对其声明.声明一个 ...

  7. excel公式与快捷操作

    将首行的公式,运用到这一整列 1.选中要输入公式的第一个单元格,SHIFT+CTRL+方向键下,在编辑栏中输入公式,按下CTRL+回车: 2.先输入要填充的公式,按下SHIFT+CTRL+方向键下,再 ...

  8. prefetch和preload

    前面的话 基于VUE的前端小站改造成SSR服务器端渲染后,HTML文档会自动使用preload和prefetch来预加载所需资源,本文将详细介绍preload和prefetch的使用 资源优先级 在介 ...

  9. netty系列之:来,手把手教你使用netty搭建一个DNS tcp服务器

    目录 简介 搭建netty服务器 DNS服务器的消息处理 DNS客户端消息请求 总结 简介 在前面的文章中,我们提到了使用netty构建tcp和udp的客户端向已经公布的DNS服务器进行域名请求服务. ...

  10. 单例模式实现的多种方式、pickle序列化模块、选课系统需求分析等

    目录 单例模式实现的多种方式 方式一: 方式二: 方式三 方式四 pickle序列化模块 选课系统需求分析 功能提炼 选课系统架构设计 三层架构 选课系统目录搭建 选课系统功能搭建 单例模式实现的多种 ...