P8701 [蓝桥杯 2019 国 B] 第八大奇迹
简要题意
你需要维护一个长度为 \(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] 第八大奇迹的更多相关文章
- 第十届蓝桥杯2019年C/C++ 大学A组省赛试题
2019年蓝桥杯第十届软件类省赛 C/C++ 大 学 A 组 试题 A: 平方和 本题总分:5 分 [问题描述] 小明对数位中含有 2.0.1.9 的数字很感兴趣,在 1 到 40 中这样的数包括 1 ...
- 第十届蓝桥杯2019年C/C++ 大学B组省赛试题
2019年第十届蓝桥杯大赛软件类省赛C/C++大学B组 试题 A:组队 本题总分:5分 [问题描述] 作为篮球队教练,你需要从以下名单中选出 1号位至 5号位各一名球员, 组成球队的首发阵容. 每位球 ...
- 今日学习——蓝桥杯 2019年 C语言 B组
1.手淦(亲身体验,,,没啥大用,最终还是代码) 2.代码(下面是我看其他博主代码答案能看的懂的....具体的可以直接去下面的网址看) https://blog.csdn.net/qq_4452491 ...
- 蓝桥杯2019初赛]迷宫(dfs版本)
传送门 大意: 题目的意思还是模板的搜索,不同的是我们要记录路径了,而且是最短字典序最小的路径. 思路: 1.对于字典序最小,也就是说我们要尽量先往下走,然后是左- 这个很简单,因为在dfs中是顺序枚 ...
- 平方十位数(蓝桥杯第八届国赛真题 JAVA-B组)
思路:从大到小枚举,判断其平方是否不重复 答案:9814072356 //水题 标题:平方十位数 由0~9这10个数字不重复.不遗漏,可以组成很多10位数字. 这其中也有很多恰好是平方数(是某个数的平 ...
- 2019第十届蓝桥杯省赛及国赛个人总结(java-B组)
省赛: 今年省赛的题目比18年简单的多,基本都是暴力枚举.BFS之类.还记得去年在山师考蓝桥杯,我这种辣鸡连题目都没看懂.本以为蓝桥会变得越来越难,没想到今年就被打脸了.今年省赛后面三个编程大题一个没 ...
- 2019年第十届蓝桥杯国赛总结(JavaA组)
JavaA组国二,可以报销了~ JA死亡之组可不是盖的,rank12的排名还是拿不到国一啊(只有五个.. 出成绩的一刻波澜不惊,毕竟去年有国一了不慌哈哈哈 不过对我来说这个结果还算意料之外吧,毕竟大三 ...
- 2019年第十届蓝桥杯省赛总结(JavaA组)
//update3.28:省一rank4,莫名进了国赛好神奇.. 记yzm10第一次体验A组(纯粹瞎水). 早闻山东的JavaA组神仙打架,进国赛都成了奢望(往年只有五个名额),因此抱着做分母的心态来 ...
- 记 2019蓝桥杯校内预选赛(JAVA组) 赛后总结
引言 好像博客好久没更新了 哈哈哈哈哈 趁现在有空更新一波 不知道还有没有人看 确实该记录一下每天做了什么了 不然感觉有些浑浑噩噩了 比赛介绍 全称: 蓝桥杯全国软件和信息技术专业人才大赛 蓝桥杯 实 ...
- 蓝桥杯第十届真题B组(2019年)
2019年第十届蓝桥杯大赛软件类省赛C/C++大学B组# 试题 A:组队# 本题总分:5分[问题描述]作为篮球队教练,你需要从以下名单中选出 1号位至 5号位各一名球员,组成球队的首发阵容.每位球员担 ...
随机推荐
- AT24C02
AT24C02是一款拥有256bytes(32Page)的EEPROM. 一 :特点(部分) 1:双线接口: 2:双向数据传输协议: 3:400KHz波特率: 4:硬件写保护: 5:最大5ms写入同步 ...
- PaddleOCR-EAST
目录 EAST Abstract Train PreProcess Architecture Backbone Neck Head Loss Dice Loss SmoothL1 Loss Infer ...
- 知识图谱顶会论文(ACL-2022) PKGC:预训练模型是否有利于KGC?可靠的评估和合理的方法
PKGC:预训练模型是否有利于KGC?可靠的评估和合理的方法 论文地址:Do Pre-trained Models Benefit Knowledge Graph Completion? A Reli ...
- 乾象投资:基于JuiceFS 构建云上量化投研平台
背景 乾象投资 Metabit Trading 成立于2018年,是一家以人工智能为核心的科技型量化投资公司.核心成员毕业于 Stanford.CMU.清北等高校.目前,管理规模已突破 30 亿元人民 ...
- python删除某一文件夹下的重复文件
#2022-10-28 import hashlib import os import time def getmd5(filename): """ 获取文件 md5 码 ...
- JAVA语言学习-面向对象(1)
类与对象 类 类是JAVA语言中重要的复合型数据类型().类的实现包括两个部分:成员变量和成员方法("方法"可以看作是C语言中的函数) 类的声明 要使用类,首先得对其声明.声明一个 ...
- excel公式与快捷操作
将首行的公式,运用到这一整列 1.选中要输入公式的第一个单元格,SHIFT+CTRL+方向键下,在编辑栏中输入公式,按下CTRL+回车: 2.先输入要填充的公式,按下SHIFT+CTRL+方向键下,再 ...
- prefetch和preload
前面的话 基于VUE的前端小站改造成SSR服务器端渲染后,HTML文档会自动使用preload和prefetch来预加载所需资源,本文将详细介绍preload和prefetch的使用 资源优先级 在介 ...
- netty系列之:来,手把手教你使用netty搭建一个DNS tcp服务器
目录 简介 搭建netty服务器 DNS服务器的消息处理 DNS客户端消息请求 总结 简介 在前面的文章中,我们提到了使用netty构建tcp和udp的客户端向已经公布的DNS服务器进行域名请求服务. ...
- 单例模式实现的多种方式、pickle序列化模块、选课系统需求分析等
目录 单例模式实现的多种方式 方式一: 方式二: 方式三 方式四 pickle序列化模块 选课系统需求分析 功能提炼 选课系统架构设计 三层架构 选课系统目录搭建 选课系统功能搭建 单例模式实现的多种 ...