https://codeforc.es/contest/1199/problem/D

其实后来想了一下貌似是个线段树的傻逼题。

单调栈是这样思考的,每次单点修改打上一个最终修改的时间戳。每次全体修改就push进去单调栈。首先比新的全体修改的x小的(等的也)全部出栈,这样子单调栈里面就是一个递减的序列,而时间戳是递增的。

最后对于每一个有修改标记的,在时间戳上面二分找到他的下一次修改,那么这个修改绝对就是足够大的。假如没有查找成功,则说明不存在最后一次修改。(可以通过在最后入栈一个0操作来统一),没有修改标记的那就直接赋值最大的全体修改。(相当于对0进行查询)

其实也是nlogn的。常数估计更小。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; inline int read() {
int x = 0;
char c = getchar();
for(; c < '0' || c > '9'; c = getchar());
for(; c >= '0' && c <= '9'; c = getchar())
x = (x << 3) + (x << 1) + c - '0';
return x;
} inline void _write(int x) {
if(x > 9)
_write(x / 10);
putchar(x % 10 + '0');
} inline void write(int x) {
if(x < 0) {
putchar('-');
x = -x;
}
_write(x);
putchar('\n');
} const int MAXN=200005; int n, q;
int a[MAXN],lc[MAXN];
int st1[MAXN],st2[MAXN],stop; int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
n = read();
for(int i = 1; i <= n; ++i)
a[i] = read(); q = read();
for(int qi = 1; qi <= q; qi++) {
int op = read(), p, x;
if(op == 1) {
p = read(), x = read();
a[p] = x;
lc[p] = qi;
} else {
x = read();
while(stop && st1[stop] <= x)
--stop;
st1[++stop] = x;
st2[stop] = qi;
}
}
st1[++stop] = 0;
st2[stop] = q + 1;
for(int i = 1; i <= n; ++i)
a[i] = max(a[i], st1[lower_bound(st2 + 1, st2 + 1 + stop, lc[i]) - st2]);
for(int i = 1; i <= n; ++i)
printf("%d%c", a[i], " \n"[i == n]);
}

其实当时也在想,每次lazy更新2操作不就可以了吗?这样就直接是线段树。每次对点更新把一路上的lazy标记push下去,然后到叶子的时候把这个失效的lazy给清空了。query的时候记得要max上lazy,因为有一些叶子并没有被1操作对点更新但是lazy也确实传到这个叶子了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int MAXM = 200000;
int a[MAXM + 5];
int lazy[(MAXM << 2) + 5]; inline void push_down(int o, int l, int r) {
if(lazy[o]) {
lazy[o << 1] = max(lazy[o << 1], lazy[o]);
lazy[o << 1 | 1] = max(lazy[o << 1 | 1], lazy[o]);
lazy[o] = 0;
}
} void update1(int o, int l, int r, int x, int v) {
if(x <= l && r <= x) {
lazy[o]=0;
a[x] = v;
return;
} else {
push_down(o, l, r);
int m = (l + r) >> 1;
if(x <= m)
update1(o << 1, l, m, x, v);
if(x >= m + 1)
update1(o << 1 | 1, m + 1, r, x, v);
}
} void update2(int o, int l, int r, int v) {
lazy[o] = max(lazy[o], v);
return;
} int query(int o, int l, int r, int x) {
if(x <= l && r <= x) {
return max(a[x], lazy[o]);
} else {
push_down(o, l, r);
int m = (l + r) >> 1;
if(x <= m)
return query(o << 1, l, m, x);
if(x >= m + 1)
return query(o << 1 | 1, m + 1, r, x);
}
} int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
//freopen("Yinku.out", "w", stdout);
#endif // Yinku
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
int q;
scanf("%d", &q);
for(int i = 1; i <= q; ++i) {
int op;
scanf("%d", &op);
if(op == 1) {
int x, v;
scanf("%d%d", &x, &v);
update1(1, 1, n, x, v);
} else {
int x;
scanf("%d", &x);
update2(1, 1, n, x);
}
}
for(int i = 1; i <= n; ++i) {
a[i] = query(1, 1, n, i);
printf("%d%c", a[i], " \n"[i == n]);
}
}

Codeforces - 1199D - Welfare State - 单调栈 / 线段树的更多相关文章

  1. [Codeforces 1199D]Welfare State(线段树)

    [Codeforces 1199D]Welfare State(线段树) 题面 给出一个长度为n的序列,有q次操作,操作有2种 1.单点修改,把\(a_x\)修改成y 2.区间修改,把序列中值< ...

  2. 洛谷P4198 楼房重建 单调栈+线段树

    正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...

  3. 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)

    2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...

  4. The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...

  5. 2019南昌网络赛-I(单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...

  6. 网络赛 I题 Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...

  7. 南昌邀请赛I.Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 Alice has a magic array. She suggests that the value of a in ...

  8. [CF1083D]The Fair Nut’s getting crazy[单调栈+线段树]

    题意 给定一个长度为 \(n\) 的序列 \(\{a_i\}\).你需要从该序列中选出两个非空的子段,这两个子段满足 两个子段非包含关系. 两个子段存在交. 位于两个子段交中的元素在每个子段中只能出现 ...

  9. 【CF671E】Organizing a Race 单调栈+线段树

    [CF671E]Organizing a Race 题意:n个城市排成一排,每个城市内都有一个加油站,赛车每次经过第i个城市时都会获得$g_i$升油.相邻两个城市之间由道路连接,第i个城市和第i+1个 ...

随机推荐

  1. 查看jar包内容

    查看jar包内容 查看jar包内容的基本命令: jar tf jar-file 参数解释: The t option indicates that you want to view the table ...

  2. NOIP2015 D1T1 神奇的幻方

    洛谷P2615 很简单的模拟题……每枚举一个点只要保存上一个点的x,y值即可,不用开数组存放 另外题目中对于K的操作都在K-1的九宫格范围内,所以我们巧妙运用++和--就可以做到每个分支一行代码 还有 ...

  3. 【LuoguP3270】[JLOI2016] 成绩比较

    题目链接 题目描述 G系共有n位同学,M门必修课.这N位同学的编号为0到N-1的整数,其中B神的编号为0号.这M门必修课编号为0到M-1的整数.一位同学在必修课上可以获得的分数是1到Ui中的一个整数. ...

  4. Python中decode与encode的区别

    摘抄: 字符串在Python内部的表示是Unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符解码(decode)成unicode,再从unicode编码 ...

  5. kali安装docker以及配置阿里云镜像加速

    1.需求 最近需要用到docker比较多,遂安装使用下,第一次用docker搭建测试环境,不得不说,docker真香.期间遇到了比较多奇奇怪怪的问题,网上的教程也比较多比较乱,遂记录一下. 2.安装d ...

  6. CSS3——制作正在加载页面loading...

    今天做了好多小东西,还挺开心的~ <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  7. A Network in a Laptop: Rapid Prototyping for Software-Defined Networks

    文章名称:A Network in a Laptop: Rapid Prototyping for  Software-Defined Networks 文章来源:Lantz B , Heller B ...

  8. Oracle Select语句

    Oracle Select语句 作者:初生不惑 Oracle基础 评论:0 条 Oracle技术QQ群:175248146 在本教程中,将学习如何使用Oracle SELECT语句从单个表中查询数据. ...

  9. js中switch语句不执行

    参考http://www.jb51.net/article/54393.htm switch语句与if语句的关系最为密切,也是其它编程语言中普遍使用的一种流程控制语句,但switch的匹配是全等模式, ...

  10. 12 Django组件-form组件

    知识预览 forms组件 forms组件 校验字段功能 针对一个实例:注册用户讲解. 模型:models.py class UserInfo(models.Model): name=models.Ch ...