\(des\)

存在参数数组 \(a\),\(a\) 升序排列

\[a_1 < a_2 < \cdots < a_m, m <= 10
\]

存在长度为 \(n\) 价值数组 \(val\)

存在 \(3\) 中操作

  1. 使区间 \([l, r]\) 内的 \(val\) 增加 \(x\)
  2. 单点修改 \(x\)
  3. 给定区间 \([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 线段树+时间复杂度分析的更多相关文章

  1. hdu 4117 -- GRE Words (AC自动机+线段树)

    题目链接 problem Recently George is preparing for the Graduate Record Examinations (GRE for short). Obvi ...

  2. BZOJ2434:[NOI2011]阿狸的打字机(AC自动机,线段树)

    Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...

  3. [CSP-S模拟测试]:模板(ac)(线段树启发式合并)

    题目描述 辣鸡$ljh\ NOI$之后就退役了,然后就滚去学文化课了.他每天都被$katarina$大神虐,仗着自己学过一些姿势就给$katarina$大神出了一道题.有一棵$n$个节点的以$1$号节 ...

  4. hdu 4117 GRE Words (ac自动机 线段树 dp)

    参考:http://blog.csdn.net/no__stop/article/details/12287843 此题利用了ac自动机fail树的性质,fail指针建立为树,表示父节点是孩子节点的后 ...

  5. HDU 5069 Harry And Biological Teacher(AC自动机+线段树)

    题意 给定 \(n\) 个字符串,\(m\) 个询问,每次询问 \(a\) 字符串的后缀和 \(b\) 字符串的前缀最多能匹配多长. \(1\leq n,m \leq 10^5\) 思路 多串匹配,考 ...

  6. AC日记——线段树练习5 codevs 4927

    4927 线段树练习5  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 有n个数和5种操作 add a b ...

  7. noi.ac #44 链表+树状数组+思维

    \(des\) 给出长度为 \(n\) 的序列,全局变量 \(t\),\(m\) 次询问,询问区间 \([l, r]\) 内出现次数为 \(t\) 的数的个数 \(sol\) 弱化问题:求区间 \([ ...

  8. 背单词(AC自动机+线段树+dp+dfs序)

    G. 背单词 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较   题目描述 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使 ...

  9. Codeforces 679E - Bear and Bad Powers of 42(线段树+势能分析)

    Codeforces 题目传送门 & 洛谷题目传送门 这个 \(42\) 的条件非常奇怪,不过注意到本题 \(a_i\) 范围的最大值为 \(10^{14}\),而在值域范围内 \(42\) ...

随机推荐

  1. gradle中引用本地项目

    例如在别的地方有一个 apiProject,里面有 apiModule,你想要引用,而不是复制到现有项目,那么 1.现有项目的settings.gradle下 include ':apiModule' ...

  2. golang --iota 用法

    package main import "fmt" func main() { const ( a = iota //0 b //1 c //2 d = "ha" ...

  3. 访问Harbor报502 Bad Gateway

    Harbor启动都是多个容器的,首先查看一下是否有相关容器未启动 docker ps | grep harbor cae340214e57 goharbor/nginx-photon:v1.9.3 & ...

  4. Java的集合整理

    1.List和Set都是接口,他们都继承于接口Collection,List是一个有序的可重复的集合,而Set的无序的不可重复的集合.Collection是集合的顶层接口,Collections是一个 ...

  5. Net core 2.x 升级 3.0 使用自带 System.Text.Json 时区 踩坑经历

    .Net Core 3.0 更新的东西很多,这里就不多做解释了,官方和博园大佬写得很详细 关于 Net Core 时区问题,在 2.1 版本的时候,因为用的是 Newtonsoft.Json,配置比较 ...

  6. LVS简单理解

    LVS LVS(Linux Virtual Server)即Linux虚拟服务器 目前LVS已经被集成到Linux内核模块中.该项目在Linux内核中实现了基于IP的数据请求负载均衡调度方案 终端用户 ...

  7. OS UIButton之UIButtonType详解-转

    我做了一个关于UIButtonType的Demo,效果如下图: UIButtonType各个类型的解释: typedef NS_ENUM(NSInteger, UIButtonType) { UIBu ...

  8. 如何让django模型中的字段和model名显示为中文

    如何让django模型中的字段和model名显示为中文:在模型中加入class Meta即可 class People(models.Model): name = models.CharField(n ...

  9. 七分钟理解 Java 的反射 API

    像java一样,一种具有反射功能的语言.允许开发人员在运行时检查类型.方法.字段.注解等,并在程序运行时决定是否使用. 为此,Java的反射API提供类,类,字段,构造函数,方法,注释和其他. 使用它 ...

  10. MySql时区修改

    1.查看当前时间 > select curtime(); #或select now()也可以+-----------+| curtime() |+-----------+| 15:18:10 | ...