P8618 [蓝桥杯 2014 国 B] Log 大侠
简要题意
给你一个长度为 \(n\) 的正整数序列 \(a\),有 \(m\) 个询问,每一个询问给出一个区间 \([l,r]\)。定义函数 \(f(x)=\lfloor\log_{2}(x)+1\rfloor\)。将 \([l,r]\) 的所有元素 \(a_p\) 修改为 \(f(a_p)\)。然后输出序列 \(a\) 的全局和。
对于 \(100\%\) 的数据,\(1 \leq n,m \le 10^5,1 \leq a_i \leq 10^9\)。
思路
前置知识:线段树。
这一道题是无标记区间修改线段树(我自己取得名字)的模板题。
这道题如果使用普通的线段树区间修改(打标记法),无论是标记下传还是标记永久化,都有一个问题:如何实现区间更新?也就是说知道 \(\sum_{i=l}^{r}{a_i}\),如何求 \(\sum_{i=l}^{r}{f(a_i)}\)?
这不是不好求,是不能求。
那我们考虑回归暴力。暴力思路很简单,在线段树上找到 \([l,r]\) 的所有元素,一一单点更新即可。
接下来见证奇迹的时刻:首先,易证当 \(x=1\) 或 \(x=2\) 时,\(f(x)=x\)。
那我们只需要再维护一个区间最大值,如果线段树遍历到的区间最大值 \(\leq 2\),那么直接不用更新了,返回。
这样子似乎复杂度没变?不不不,复杂度已经变成了 \(O(\alpha(a_i)n)\)!
这里给出简单证明过程:首先,\(f(i)\approx \log_{2}(i)\),也就是说,单次 \(f(i)\) 时缩减到了 \(\log(i)\) 级。
所以如果令 \(x\) 递归 \(k(x)\) 到 \(1\)。我们发现 \(k(x)\) 不太好求,于是我们反过来知道 \(x\) 求 \(k(x)\):
\]
下面我们把上式简写为 \(2@k(x)=x\)。
自然想到阿克曼函数 \(A(2,k(x))=2@k(x)=x\)。然后 \(k(x)\) 就是和 \(\alpha(x)\) 同阶了。
均摊时间复杂度分析:由于每一个元素最多被单点修改 \(\alpha(10^9)\approx 3\) 次。所以均摊时间复杂度是 \(O(3n)\)。
这就是无标记区间修改线段树。课后习题还有几道无标记区间修改线段树的题,供大家练习。
课后习题:
- P4145 上帝造题的七分钟 2 / 花神游历各国
- mod 板线段树(学长出的线段树神仙题)
代码
#include <bits/stdc++.h>
#define int long long
#define ls (i<<1)
#define rs (i<<1|1)
#define mid ((l+r)>>1)
using namespace std;
int n,m;
const int N = 1e5+5;
struct node{
int maxt,sumt;
} t[N<<2];
inline void pushup(int i){
t[i].maxt=max(t[ls].maxt,t[rs].maxt);
t[i].sumt=t[ls].sumt+t[rs].sumt;
}
void build(int i,int l,int r){
if(l==r){
cin>>t[i].maxt;
t[i].sumt=t[i].maxt;
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
pushup(i);
}
inline int magic(int x){
return floor(log(x)/log(2)+1);
}
void update(int ql,int qr,int i,int l,int r){
if(t[i].maxt<=2){
return;
}
if(l==r){
t[i].sumt=t[i].maxt=magic(t[i].sumt);
return;
}
if(ql<=mid){
update(ql,qr,ls,l,mid);
}
if(qr>mid){
update(ql,qr,rs,mid+1,r);
}
pushup(i);
}
int query(int ql,int qr,int i,int l,int r){
if(ql<=l&&r<=qr){
return t[i].sumt;
}
int ret=0;
if(ql<=mid){
ret += query(ql,qr,ls,l,mid);
}
if(qr>mid){
ret += query(ql,qr,rs,mid+1,r);
}
return ret;
}
signed main(){
cin>>n>>m;
build(1,1,n);
while(m--){
int l,r;
cin>>l>>r;
update(l,r,1,1,n);
cout<<query(1,n,1,1,n)<<'\n';
}
return 0;
}
(听说有人抄我的交题解,我劝你善良)
P8618 [蓝桥杯 2014 国 B] Log 大侠的更多相关文章
- 2014年第五届蓝桥杯国赛 Log大侠(区间合并+Java递归效率分析)
1678: Log大侠 java 时间限制: 2 Sec 内存限制: 256 MB提交: 20 解决: 1 题目描述 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称L ...
- 蓝桥杯 2014本科C++ B组 奇怪的分式 暴力枚举
蓝桥杯 枚举 奇怪的分式 标题:奇怪的分式 上小学的时候,小明经常自己发明新算法.一次,老师出的题目是: 1/4 乘以 8/5 小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1 ...
- [蓝桥杯]2014蓝桥省赛B组题目及详解
/*——————————————————————————————————————————————————————————— [结果填空题]T1 题目:啤酒和饮料 啤酒每罐2.3元,饮料每罐1.9元.小 ...
- 蓝桥杯 2014本科C++ B组 李白打酒 三种实现方法 枚举/递归
标题:李白打酒 话说大诗人李白,一生好饮.幸好他从不开车. 一天,他提着酒壶,从家里出来,酒壶中有酒2斗.他边走边唱: 无事街上走,提壶去打酒. 逢店加一倍,遇花喝一斗. 这一路上,他一共遇到店5次, ...
- 蓝桥杯 2014本科C++ B组 六角填数 枚举排列
标题:六角填数 如图[1.png]所示六角形中,填入1~12的数字. 使得每条直线上的数字之和都相同. 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少? 请通过浏览器提交答案,不要填 ...
- 蓝桥杯 2014本科C++ B组 地宫取宝 DFS+记忆化搜索
历届试题 地宫取宝 时间限制:1.0s 内存限制:256.0MB 问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角 ...
- 平方十位数(蓝桥杯第八届国赛真题 JAVA-B组)
思路:从大到小枚举,判断其平方是否不重复 答案:9814072356 //水题 标题:平方十位数 由0~9这10个数字不重复.不遗漏,可以组成很多10位数字. 这其中也有很多恰好是平方数(是某个数的平 ...
- 【蓝桥杯真题】地宫取宝(搜索->记忆化搜索详解)
链接 [蓝桥杯][2014年第五届真题]地宫取宝 题目描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被 ...
- 蓝桥杯Log大侠(线段树单点区间更新)
标题:Log大侠 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠. 一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力... 变换的规则是: ...
- java实现第五届蓝桥杯LOG大侠
LOG大侠 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠. 一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力- 变换的规则是: 对其某个 ...
随机推荐
- 1NF | 2NF | 3NF的区分以及什么是函数依赖、部分函数依赖、值传递依赖(最详细的讲解1NF、2NF、3NF的关系)
1NF | 2NF | 3NF的区分以及什么是函数依赖.部分函数依赖.值传递依赖 符合3NF一定符合2NF.一定符合1IF 简单区分.2NF不存在部分函数依赖,3NF不存在传递函数依赖 第一范式1NF ...
- 齐博x1如何取消某个标签的缓存时间
标签默认会有缓存, 如果你要强制取消缓存时间的话, 可以加上下面的参数 time="-1"如下图所示 标签默认缓存时间是10分钟, 你也可以改成其它时间 比如 time=" ...
- 齐博x1嵌套-循环栏目,并列出子栏目下的内容
嵌套,循环栏目,并列出子栏目下的内容. 代码如下: <div class="channel-list"> <div class="row"&g ...
- antd 批量上传文件逻辑
基本步骤 通过 antd 框架的 Upload 控件,采用手动上传的方式,先选择需要上传的文件(控制文件数量以及大小),再根据所选的文件列表,循环上传,期间通过 Spin 控件提示上传中. 效果展示 ...
- 【笔记】CF1659E AND-MEX Walk 及相关
题目传送门 位运算 设题目中序列 \(w_1,w_1\& w_2,w_1\& w_2\& w_3,\dots,w_1\& w_2\& \dots \& ...
- SpringBoot 08: SpringBoot综合使用 MyBatis, Dubbo, Redis
业务背景 Student表 CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) COL ...
- 基于k8s的发布系统的实现
综述 首先,本篇文章所介绍的内容,已经有完整的实现,可以参考这里. 在微服务.DevOps和云平台流行的当下,使用一个高效的持续集成工具也是一个非常重要的事情.虽然市面上目前已经存在了比较成熟的自动化 ...
- kotlin的suspend对比csharp的async&await
协程的出现大大降低了异步编程的复杂度,可以让我们像写同步代码一样去写异步代码,如果没有它,那么很多异步的代码都是需要靠回调函数来一层层嵌套,这个在我之前的一篇有介绍 rxjava回调地狱-kotlin ...
- 如何使用zx编写shell脚本
前言 在这篇文章中,我们将学习谷歌的zx库提供了什么,以及我们如何使用它来用Node.js编写shell脚本.然后,我们将学习如何通过构建一个命令行工具来使用zx的功能,帮助我们为新的Node.js项 ...
- variant conversion error for variable:v8
oracle 添加表数据报错:variant conversion error for variable:v8. 是数据类型不匹配.