Codeforces - 1199D - Welfare State - 单调栈
Posted yinku
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces - 1199D - Welfare State - 单调栈相关的知识,希望对你有一定的参考价值。
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]);
以上是关于Codeforces - 1199D - Welfare State - 单调栈的主要内容,如果未能解决你的问题,请参考以下文章