吉司机线段树思路整理[bzoj4355 Play with sequence]
Posted hjmmm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了吉司机线段树思路整理[bzoj4355 Play with sequence]相关的知识,希望对你有一定的参考价值。
#include<cstdio>
#include<algorithm>
#define LL long long
//#define int long long
using namespace std;
const int MAXN = 3 * 1e5 + 10;
const LL INF = 1e10 +10;
inline int read()
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') if(c == '-') f = -1; c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
#define ls k << 1
#define rs k << 1 | 1
int N, Q;
int a[MAXN];
struct Node
int l, r, siz有多宽, cnt有几个最小值;
LL Mx最小值标记, add加法标记, mn最小值, se次小值, cov刷值标记;
T[MAXN << 2];
void update(int k)
更新mn, se, cnt
void MemP(int k, LL val)
打刷值标记 cnt变成size 最小值变成val
void AddP(int k, LL val)
如果有次大值,最小值标记 add它
最小值标记和加法标记是肯定要更新的
void MaxP(int k, LL val)
刷新mn, mx
void pushdown(int k)
如果有刷值标记 下放mem
如果有add标记 下放add
如果有最小值更新标记 下放max操作
记得清空标记
void Build(int k, int ll, int rr)
初始化
if(ll == rr) 最小值是自己,有一个
下推,update
void IntMem(int k, int ll, int rr, LL val) //下放刷值操作
if(位于目标区间) 执行mem操作
pushdown,下推,update
void IntAdd(int k, int ll, int rr, LL val) //下放add操作
if(位于目标区间) 执行add操作
pushdown,下推,update
void IntMax(int k, int ll, int rr, LL val) //下放取max操作
if(val比最小值小) return ;
if(位于目标区间并且val在(最小值,次小值)时,只对最小值有影响) 执行max操作;
pushdown,下推,update
LL Query()
if(ll <= T[k].l && T[k].r <= rr) 如果最小数是0 返回有几个 不然就是没有啦
pushdown并下推
main()
N = read(); Q = read();
for(int i = 1; i <= N; i++) a[i] = read();
Build(建树); 树中不会有小于0的数哦
while(Q--)
int opt = read(), l = read(), r = read(), val;
if(opt == 3) printf("%d\\n", Query(询问区间中值为0的个数));
else
val = read();
if(opt == 1) IntMem(给区间每个数赋值);
else
IntAdd(给区间每个数加x);
IntMax(判断区间每个数和0的大小,并更新);
return 0;
以上是关于吉司机线段树思路整理[bzoj4355 Play with sequence]的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ4355Play with sequence 线段树