简要题意

你需要维护一个长度为 \(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. hyperf-搭建初始化

    官方文档* https://hyperf.wiki/2.0/#/README 初步搭建1. 安装项目 composer create-project hyperf/hyperf-skeleton 2. ...

  2. 6.channels 配置websocket

      Django默认不支持websockey,需要Django支持的话需要安装第三方组件 django channels 是django支持websocket的一个模块.   1.安装 pip3 in ...

  3. Java 动态代理原理图解 (附:2种实现方式详细对比)

    ​ 动态代理在 Java 中有着广泛的应用,例如:Spring AOP 面向切面编程,Hibernate 数据查询.以及 RPC Dubbo 远程调用等,都有非常多的实际应用@mikechen 目录 ...

  4. vulnhub靶场之CORROSION: 2

    准备: 攻击机:虚拟机kali.本机win10. 靶机:CORROSION: 2,网段地址我这里设置的桥接,所以与本机电脑在同一网段,下载地址:https://download.vulnhub.com ...

  5. 嵌入式-C语言基础:结构体

    数组只能存放一种类型的数据,而结构体内可以存放不同类型的数据. #include<stdio.h> #include <string.h> struct Student { c ...

  6. Node.js的学习(一)node.js 的介绍

    一.简介 1.1.什么是 node.js ? node.js  一种 JavaScript 的运行环境,能够使得javascript能够脱离浏览器运行.以前 js 只能在浏览器基础上运行,能够操作的也 ...

  7. 论文翻译:2022_DeepFilterNet2: Towards Real-Time Speech Enhancement On Embedded Devices For Fullband Audio

    博客地址:凌逆战 论文地址:DeepFilternet2: 面向嵌入式设备的全波段音频实时语音增强 论文代码:https://github.com/Rikorose/DeepFilterNet 引用格 ...

  8. 2022春每日一题:Day 30

    题目:[JSOI2009]电子字典 读完题后,暴力?确实,计算一下时间复杂度最坏情况下,20263*10000=1.5e8,卡一下常可以直接卡到7e7,最严格来说应该卡的过去,但是此题数据可以直接卡过 ...

  9. django 多 APP urls的实现

    项目下urls.py 引入admin from django.contrib import admin 引入path,include from django.urls import path,incl ...

  10. 基于python的数学建模---二维插值的三维图

    import numpy as np from mpl_toolkits.mplot3d import Axes3D import matplotlib as mpl from scipy impor ...