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\) ...
随机推荐
- golang--获取进程ID(windows)
package main import ( "fmt" "strconv" "syscall" "unsafe" ) t ...
- docker查看容器日志
原文:docker查看容器日志 前言 $ sudo docker logs -f -t --tail 行数 容器名 1 2 1.命令查看 root@c68d4b5dd583c4f4ea30da2989 ...
- 第三方dll签名
1.打开vs Tools下的工具命令 2.生成随机密钥对C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC>sn -k NonSignL ...
- vue使用vuex大体结构
store1.js const state = {} const mutations = {} const actions = {} const getters = {} export default ...
- CSS是什么
css是层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言. CSS不 ...
- 十、vue mixins 的用法
vue中mixins个人理解就是定义一些公用的比较常用的方法,类似我们vue中将一些常用的组件也会抽离出来做成一个公共组件一样,只不过vue中mixins是定义的是法或者计算属性,然后将其混入(合并) ...
- maccms 山寨站点 V10 后门
经验证:www.maccmsv10应该是个山寨站 -------------------- 前言 苹果CMS是国内优秀的开源PHP建站系统,擅长电影程序影视系统这一块,在主流建站系统中特色鲜明,以灵活 ...
- Spring @Transactional注解不起作用解决办法及原理分析
Transactional失效场景介绍 第一种 Transactional注解标注方法修饰符为非public时,@Transactional注解将会不起作用.例如以下代码. 定义一个错误的@Trans ...
- 二十三、mysql索引管理详解
一.索引分类 分为聚集索引和非聚集索引. 聚集索引 每个表有且一定会有一个聚集索引,整个表的数据存储在聚集索引中,mysql索引是采用B+树结构保存在文件中,叶子节点存储主键的值以及对应记录的数据,非 ...
- ASP.NET 取得 Request URL 的各个部分和通过ASP.NET获取URL地址的方法
网址:http://localhost:1897/News/Press/Content.aspx/123?id=1#toc Request.ApplicationPath / Request.Phys ...