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\) ... 
随机推荐
- mysql删除字符串的前后的空格
			update table set field = replace(replace(replace(field,char(9),''),char(10),''),char(13),''); 
- git学习笔记 ---管理修改
			现在,假定你已经完全掌握了暂存区的概念.下面,我们要讨论的就是,为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件. 你会问,什么是修改?比如你新增了一行,这就是一个修改 ... 
- go 学习笔记(1)go command
			常用命令 go command [arguments] 1) go build 跨平台编译: env GOOS=linux GOARCH=amd64 go build 2) go install : ... 
- 转:Java接口和抽象类
			转:http://www.cnblogs.com/dolphin0520/p/3811437.html 一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有声明,而没有 ... 
- Oracle——无法在查询中执行 DML 操作
			今天在调用Oracle Function遇到一个异常 
- js 简单的滑动4
			js 简单的滑动教程(四) 作者:Lellansin 转载请标明出处,谢谢 在大概的了解滑动的基本原理和怎么去实现之后,现在我们将更深入的去讨论js的滑动. 相信细心的朋友应该已经发现了,在本教程 ... 
- 易百教程人工智能python修正-人工智能监督学习(回归)
			回归是最重要的统计和机器学习工具之一. 我们认为机器学习的旅程从回归开始并不是错的. 它可以被定义为使我们能够根据数据做出决定的参数化技术,或者换言之,允许通过学习输入和输出变量之间的关系来基于数据做 ... 
- HelloWorld! C++纠错版
			例题:1 #include<iostream> int main() { cout << "HelloWorel!" ; ; } #include < ... 
- Qt 利用飞机图片画五边形
			最近练习Qt,需要一个飞机在屏幕上画五边形.虽然达到的效果不是非常的理想,但是勉强还是达到了效果,欢迎大家指正.用到的飞机图片如下. 第一步:初始化,在构造函数里面,把图片向左旋转18° );ui.l ... 
- iOS-H5交互综合整理
			1.WKWebView的使用 2.常见问题 2.1 iOS开发 WKWebView下js的alert(),confirm(),prompt()方法无法正常执行 
