CF 576 div2 D
Posted op-z
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 576 div2 D相关的知识,希望对你有一定的参考价值。
传送门:https://codeforces.com/contest/1199/problem/D
题意:给一序列,给一串操作,按顺序修改序列内容,分两种类型
类型一:1 p x ,位置p的数字改为x
类型二:2 x,序列中所有小于x的数字全改为x
刚开始想着直接线段树,单点修改和区间修改,头脑风暴了一会儿,觉着lazy标记改动容易出错,果断弃了
嘻嘻,心态放好先
开始草稿纸上乱画分析(瞎搞
对于type 2,最后改的肯定是x的最大值,一直取max就好啦
难搞的是type 1,每次改动都得看后续的type 2有没有对x有影响,就不能单纯标记了
emmmm 等等,既然只有后续的type 2对type 1有影响,而且也只有最大值会被保留,那从后往前找每个位置到末尾的最大值就好啦
一个后缀最大值数组就解决了
然后就是一些细节了,后缀最大值数组是对操作进行的,并非原序列下标,需另开个数组记录好对应关系
#include<algorithm> #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<string> #include<map> #include<queue> #include<stack> #include<list> #include<set> using namespace std; typedef long long ll; typedef pair<ll,ll> P; typedef long double ld; #define mem(x) memset(x, 0, sizeof(x)) #define me(x) memset(x, -1, sizeof(x)) #define fo(i,n) for(i=0; i<n; i++) #define sc(x) scanf("%I64d", &x) #define sca(n,m) scanf("%I64d%I64d", &n, &m) #define pr(x) printf("%I64d\n", x) #define pri(x) printf("%I64d ", x) #define lowbit(x) x&-x const ll MOD = 1e9 + 7; const ll oo = 1e18; const ll N = 4e5 + 5; ll a[N], b[N], sum[N]; map<ll,ll>mp; ll v[N], mx[N], id[N]; int main() ll i, j, k, l=1; ll n, m, t; ll x, y; sc(n); for(i=1; i<=n; i++) sc(a[i]); sc(m); ll ans=0; while(m--) sc(k); if(k==1) sca(x,y), v[l++]=-1, id[x]=l-1, mp[x]=y+1; else sc(x), v[l++]=x, ans=max(ans,x); l--; for(i=l; i>=1; i--) mx[i]=max(mx[i+1],v[i]); for(i=1; i<=n; i++) if(!mp[i]) pri(max(ans,a[i])); else pri(max(mp[i]-1,mx[id[i]])); printf("\n"); return 0;
以上是关于CF 576 div2 D的主要内容,如果未能解决你的问题,请参考以下文章
CF576E Painting Edges [线段树分治,可撤销并查集]