noi.ac #38 线段树+时间复杂度分析
\(des\)
存在参数数组 \(a\),\(a\) 升序排列
\]
存在长度为 \(n\) 价值数组 \(val\)
存在 \(3\) 中操作
- 使区间 \([l, r]\) 内的 \(val\) 增加 \(x\)
- 单点修改 \(x\)
- 给定区间 \([l, r]\) ,定义 \(f(x)\) 表示最大的 \(i\) 是的 \(a_i <= x\)
求 \(\sum_{i = l} ^ {r} f(i)\)
\(sol\)
如果没有操作2,也就是说元素不会减小,同时 \(f(x)\) 也不会减小,所有的元素
\(f(x)\) 增加一共会有 \(O(nm)\)。这里可以用线段树维护,第 \(i\) 个点维护的是
\(f(i)\) 还需要增加多少才可以增加,单次操作1相当于对区间 \([l, r]\) 做减法
,显然如果某个时刻存在某个数 \(<= 0\),这是 \(f(x)\) 需要增加,改变相关信息
,可以线段树维护区间最小值来实现。那么如果存在操作2是一样的,不过可能会
存在 \(f(x)\) 的减小的情况,并不会对时间复杂度产生大的影响
由于一共只会存在 \(O((n + q)m)\) 次增加,时间复杂度 O((n + 1)mlogn)。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
const int N = 1e5 + 10;
#define gc getchar()
#define Rep(i, a, b) for(int i = a; i <= b; i ++)
#define LL long long
inline int read() {int x = 0; char c = gc; while(c < '0' || c > '9') c = gc;
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}
inline LL readLL() {LL x = 0; char c = gc; while(c < '0' || c > '9') c = gc;
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}
int W[N << 2], F[N << 2], Minn[N << 2];
int A[15], Val[N];
int n, m, q;
#define lson jd << 1
#define rson jd << 1 | 1
void Build_tree(int l, int r, int jd) {
if(l == r) {
int x = lower_bound(A + 1, A + m + 1, Val[l]) - A;
if(A[x] > Val[l]) x --;
W[jd] = x;
Minn[jd] = A[x + 1] - Val[l];
return ;
}
int mid = (l + r) >> 1;
Build_tree(l, mid, lson), Build_tree(mid + 1, r, rson);
Minn[jd] = min(Minn[lson], Minn[rson]);
W[jd] = W[lson] + W[rson];
}
void Push_down(int jd) {
F[lson] += F[jd], F[rson] += F[jd];
Minn[lson] += F[jd], Minn[rson] += F[jd];
F[jd] = 0;
}
void Sec_G(int l, int r, int jd, int x, int y, int num) {
if(x <= l && r <= y) {
Minn[jd] -= num;
F[jd] -= num;
return ;
}
if(F[jd] != 0) Push_down(jd);
int mid = (l + r) >> 1;
if(x <= mid) Sec_G(l, mid, lson, x, y, num);
if(y > mid) Sec_G(mid + 1, r, rson, x, y, num);
Minn[jd] = min(Minn[lson], Minn[rson]);
}
void Dfs_G(int l, int r, int jd) {
if(l == r) {
int b = A[W[jd] + 1] - Minn[jd];
Val[l] = b;
int x = lower_bound(A + 1, A + m + 1, b) - A;
if(A[x] > b) x --;
W[jd] = x;
Minn[jd] = A[x + 1] - b;
return ;
}
if(F[jd]) Push_down(jd);
int mid = (l + r) >> 1;
if(Minn[lson] <= 0) Dfs_G(l, mid, lson);
if(Minn[rson] <= 0) Dfs_G(mid + 1, r, rson);
Minn[jd] = min(Minn[lson], Minn[rson]);
W[jd] = W[lson] + W[rson];
}
void Poi_G(int l, int r, int jd, int x, int num) {
if(l == r) {
Val[l] = num;
int x = lower_bound(A + 1, A + m + 1, Val[l]) - A - 1;
W[jd] = x;
Minn[jd] = A[x + 1] - Val[l];
return ;
}
if(F[jd]) Push_down(jd);
int mid = (l + r) >> 1;
if(x <= mid) Poi_G(l, mid, lson, x, num);
else Poi_G(mid + 1, r, rson, x, num);
W[jd] = W[lson] + W[rson];
Minn[jd] = min(Minn[lson], Minn[rson]);
}
int Answer;
void Sec_A(int l, int r, int jd, int x, int y) {
if(x <= l && r <= y) {
Answer += W[jd];
return ;
}
if(F[jd]) Push_down(jd);
int mid = (l + r) >> 1;
if(x <= mid) Sec_A(l, mid, lson, x, y);
if(y > mid) Sec_A(mid + 1, r, rson, x, y);
}
int main() {
n = read(), m = read(), q = read();
Rep(i, 1, m) A[i] = read();
A[m + 1] = (1 << 30);
Rep(i, 1, n) Val[i] = read();
Build_tree(1, n, 1);
Rep(t, 1, q) {
int opt = read();
if(opt == 1) {
int l = read(), r = read(), x = read();
Sec_G(1, n, 1, l, r, x);
if(Minn[1] <= 0) Dfs_G(1, n, 1);
} else if(opt == 2) {
int p = read(), x = read();
Poi_G(1, n, 1, p, x);
} else {
int x = read(), y = read();
Answer = 0;
Sec_A(1, n, 1, x, y);
cout << Answer << "\n";
}
}
return 0;
}
noi.ac #38 线段树+时间复杂度分析的更多相关文章
- hdu 4117 -- GRE Words (AC自动机+线段树)
题目链接 problem Recently George is preparing for the Graduate Record Examinations (GRE for short). Obvi ...
- BZOJ2434:[NOI2011]阿狸的打字机(AC自动机,线段树)
Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...
- [CSP-S模拟测试]:模板(ac)(线段树启发式合并)
题目描述 辣鸡$ljh\ NOI$之后就退役了,然后就滚去学文化课了.他每天都被$katarina$大神虐,仗着自己学过一些姿势就给$katarina$大神出了一道题.有一棵$n$个节点的以$1$号节 ...
- hdu 4117 GRE Words (ac自动机 线段树 dp)
参考:http://blog.csdn.net/no__stop/article/details/12287843 此题利用了ac自动机fail树的性质,fail指针建立为树,表示父节点是孩子节点的后 ...
- HDU 5069 Harry And Biological Teacher(AC自动机+线段树)
题意 给定 \(n\) 个字符串,\(m\) 个询问,每次询问 \(a\) 字符串的后缀和 \(b\) 字符串的前缀最多能匹配多长. \(1\leq n,m \leq 10^5\) 思路 多串匹配,考 ...
- AC日记——线段树练习5 codevs 4927
4927 线段树练习5 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有n个数和5种操作 add a b ...
- noi.ac #44 链表+树状数组+思维
\(des\) 给出长度为 \(n\) 的序列,全局变量 \(t\),\(m\) 次询问,询问区间 \([l, r]\) 内出现次数为 \(t\) 的数的个数 \(sol\) 弱化问题:求区间 \([ ...
- 背单词(AC自动机+线段树+dp+dfs序)
G. 背单词 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使 ...
- Codeforces 679E - Bear and Bad Powers of 42(线段树+势能分析)
Codeforces 题目传送门 & 洛谷题目传送门 这个 \(42\) 的条件非常奇怪,不过注意到本题 \(a_i\) 范围的最大值为 \(10^{14}\),而在值域范围内 \(42\) ...
随机推荐
- 【题解】Luogu P4910 帕秋莉的手环
原题传送门 "连续的两个中至少有1个金的"珂以理解为"不能有两个木相连" 我们考虑一个一个将元素加入手环 设f\([i][0/1]\)表示长度为\(i\)手环末 ...
- 长连接、短连接、长轮询和WebSocket
//转发,格式待整理 2017-08-0519784View0 对这四个概念不太清楚,今天专门搜索了解一下,总结一下: 长连接:在HTTP 1.1,客户端发出请求,服务端接收请求,双方建立连接,在服务 ...
- 树莓派Raspbian系统格式化挂载硬盘
1.查看树莓派系统挂载的储存设备 使用工具查看系统识别到的硬盘设备,命令: fdisk -l /dev/sda 和 /dev/sdb 分别是两块硬盘. 2.修改硬盘分区 Linux和windows一 ...
- CSS 各种形状
制作圆形: 要使用CSS来制作一个圆形,我们需要一个div,被给它设置一个ID <div id="circle"></div> 圆形在设置CSS时要设置宽 ...
- PHP 的一款http请求封装类
<?php namespace hisi; class Http { protected static $userAgent = [ 'Mozilla/5.0 (Windows NT 6.1; ...
- jmeter用什么查看结果报告
JMeter查看测试结果的方法很多,最常用的几种是:察看结果树.聚合报告.图形报表.邮件观察仪等.
- Oracle 检索数据(查询数据、select语句)
用户对表或视图最常进行的操作就是检索数据,检索数据可以通过 select 语句来实现,该语句由多个子句组成,通过这些子句完成筛选.投影和连接等各种数据操作,最终得到想要的结果. 语法: select ...
- 离线安装zabbix文档
为了离线安装需要离线安装包,可以通过这个方式获取. 用yum安装软件默认不保存软件包,要保存需修改配置文件 # vi /etc/yum.conf 将keepcache的值改为1 安装版本:rel ...
- Android 低功耗蓝牙BLE 开发注意事项
基本概念和问题 1.蓝牙设计范式? 当手机通过扫描低功耗蓝牙设备并连接上后,手机与蓝牙设备构成了客户端-服务端架构.手机通过连接蓝牙设备,可以读取蓝牙设备上的信息.手机就是客户端,蓝牙设备是服务端. ...
- Linux主机之间传输文件的几种方法对比
1.scp传输 scp -r /data/file root@ip:/data/ scp -C /data/sda.img root@ip:/data/img/#-r: 支持目录#-C: 启用压缩传送 ...