bzoj4695 最假女选手
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4695
【题解】
SegmentTree beats!(见jiry_2论文/营员交流)
考虑只有对p取max,区间加,查min/和怎么做。
有一道类似的题,是取min,见hdu5306.
按照segmentbeats这套理论,我们要维护最小值,最小值出现个数,次小值即可。
每次区间对$p$取max,如果当前节点满足$min < p < sec$,那么打区间max标记,而且我们也可以很方便算出每个的改变量。
标记下传的话考虑对于$x$的儿子,显然要么满足$p < min$,要么满足$min < p < sec$,直接维护即可。
这里的标记我们不需要开一个tag存,我们只要判断是否满足$min < p < sec$就知道是否下传标记了。
【考虑同时维护min/max的情况】
按照segmentbeats这套理论,我们要维护最小值,最小值出现个数,次小值;最大值,最大值出现个数,次大值即可。
对区间取min操作和上面说的取max操作类似,我们着重讨论标记下传问题。
这里涉及到标记的叠加,稍加讨论下我们发现,只要判断$min < min_x < secmin$就知道是否要把$min_x$传给儿子;同理判断$secmax < max_x < max$就知道是否要把$max_x$传给儿子。
这里还涉及到一个问题:标记下传的先后顺序。
考虑什么时候标记存在影响:因为标记都是对最大值和次大值,最小值和次小值之间的区间打的,其他都是暴力维护,所以只对区间长度小于等于2的情况产生影响。
稍加讨论我们发现,先传和后传是没有影响的。
e.g. 区间 = $[3, 6]$
父区间有标记:对于4取max,对于5取min
那么显然没有影响,正常做即可。
父区间有标记:对于5取max,对于4取min。
我们发现,对于5取max的情况,父区间序列一定变成了$[5, ...]$,这时候再对4取min,不符合标记的性质了,所以不存在这种情况。
复杂度:$O(nlog^2n)$,跑的和$O(nlogn)$差不多。
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 5e5 + , SN = + ;
const int mod = 1e9+, inf = 1e9; inline int getint() {
int x = , f = ; char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') f = ;
ch = getchar();
}
while(isdigit(ch)) {
x = (x<<) + (x<<) + ch - '';
ch = getchar();
}
return f ? x : -x;
} int n, a[N];
struct node {
int p, t, se;
node () {}
node (int p, int t, int se) : p(p), t(t), se(se) {}
inline friend node combineMax(node a, node b) {
node c;
if(a.p < b.p) {
c.p = b.p; c.t = b.t;
c.se = max(a.p, b.se);
} else if(a.p > b.p) {
c.p = a.p; c.t = a.t;
c.se = max(a.se, b.p);
} else {
c.p = a.p; c.t = a.t + b.t;
c.se = max(a.se, b.se);
}
return c;
}
inline friend node combineMin(node a, node b) {
node c;
if(a.p > b.p) {
c.p = b.p; c.t = b.t;
c.se = min(a.p, b.se);
} else if(a.p < b.p) {
c.p = a.p; c.t = a.t;
c.se = min(a.se, b.p);
} else {
c.p = a.p; c.t = a.t + b.t;
c.se = min(a.se, b.se);
}
return c;
}
inline friend node operator + (node a, int p) {
return node(a.p + p, a.t, a.se + p);
}
}; struct SMTbeats {
node mx[SN], mi[SN];
int tag[SN]; ll s[SN];
# define ls (x<<)
# define rs (x<<|)
inline void up(int x) {
mx[x] = combineMax(mx[ls], mx[rs]);
mi[x] = combineMin(mi[ls], mi[rs]);
s[x] = s[ls] + s[rs];
} // a = max(a, t)
inline void pushmax(int x, int l, int r, int p) {
s[x] += 1ll * mi[x].t * (p - mi[x].p);
mi[x].p = p; mx[x].p = max(mx[x].p, p);
if(mi[x].p == mx[x].p) {
mi[x].se = inf, mx[x].se = -inf;
mi[x].t = mx[x].t = r-l+;
s[x] = 1ll * mi[x].p * (r-l+);
} else mx[x].se = max(mx[x].se, p);
}
// a = min(a, t)
inline void pushmin(int x, int l, int r, int p) {
s[x] += 1ll * mx[x].t * (p - mx[x].p);
mx[x].p = p; mi[x].p = min(mi[x].p, p);
if(mi[x].p == mx[x].p) {
mi[x].se = inf, mx[x].se = -inf;
mi[x].t = mx[x].t = r-l+;
s[x] = 1ll * mi[x].p * (r-l+);
} else mi[x].se = min(mi[x].se, p);
}
inline void pushtag(int x, int l, int r, int p) {
tag[x] += p; s[x] += 1ll * (r-l+) * p;
mx[x] = mx[x] + p, mi[x] = mi[x] + p;
} inline void down(int x, int l, int r) {
int mid = l+r>>;
if(tag[x]) {
pushtag(ls, l, mid, tag[x]); pushtag(rs, mid+, r, tag[x]);
tag[x] = ;
}
if(mx[ls].p > mx[x].p && mx[ls].se < mx[x].p) pushmin(ls, l, mid, mx[x].p);
if(mx[rs].p > mx[x].p && mx[rs].se < mx[x].p) pushmin(rs, mid+, r, mx[x].p);
if(mi[ls].p < mi[x].p && mi[ls].se > mi[x].p) pushmax(ls, l, mid, mi[x].p);
if(mi[rs].p < mi[x].p && mi[rs].se > mi[x].p) pushmax(rs, mid+, r, mi[x].p);
} inline void build(int x, int l, int r) {
tag[x] = ;
if(l == r) {
mx[x].p = mi[x].p = s[x] = a[l], mx[x].t = mi[x].t = , mx[x].se = -inf, mi[x].se = inf;
return ;
}
int mid = l+r>>;
build(ls, l, mid);
build(rs, mid+, r);
up(x);
} inline void edt(int x, int l, int r, int L, int R, int p) {
if(L <= l && r <= R) {
pushtag(x, l, r, p);
return ;
}
down(x, l, r);
int mid = l+r>>;
if(L <= mid) edt(ls, l, mid, L, R, p);
if(R > mid) edt(rs, mid+, r, L, R, p);
up(x);
} inline void edtmin(int x, int l, int r, int L, int R, int p) {
if(mx[x].p <= p) return ;
if(L <= l && r <= R && mx[x].se < p) {
pushmin(x, l, r, p);
return ;
}
down(x, l, r);
int mid = l+r>>;
if(L <= mid) edtmin(ls, l, mid, L, R, p);
if(R > mid) edtmin(rs, mid+, r, L, R, p);
up(x);
} inline void edtmax(int x, int l, int r, int L, int R, int p) {
if(mi[x].p >= p) return ;
if(L <= l && r <= R && mi[x].se > p) {
pushmax(x, l, r, p);
return ;
}
down(x, l, r);
int mid = l+r>>;
if(L <= mid) edtmax(ls, l, mid, L, R, p);
if(R > mid) edtmax(rs, mid+, r, L, R, p);
up(x);
} inline int gmax(int x, int l, int r, int L, int R) {
if(L <= l && r <= R) return mx[x].p;
down(x, l, r);
int mid = l+r>>, ret = -inf;
if(L <= mid) ret = max(ret, gmax(ls, l, mid, L, R));
if(R > mid) ret = max(ret, gmax(rs, mid+, r, L, R));
return ret;
} inline int gmin(int x, int l, int r, int L, int R) {
if(L <= l && r <= R) return mi[x].p;
down(x, l, r);
int mid = l+r>>, ret = inf;
if(L <= mid) ret = min(ret, gmin(ls, l, mid, L, R));
if(R > mid) ret = min(ret, gmin(rs, mid+, r, L, R));
return ret;
} inline ll gsum(int x, int l, int r, int L, int R) {
if(L <= l && r <= R) return s[x];
down(x, l, r);
int mid = l+r>>; ll ret = ;
if(L <= mid) ret += gsum(ls, l, mid, L, R);
if(R > mid) ret += gsum(rs, mid+, r, L, R);
return ret;
} inline void debug(int x, int l, int r) {
printf("%d %d %d [%d %d %d] [%d %d %d] %I64d\n", x, l, r, mx[x].p, mx[x].t, mx[x].se, mi[x].p, mi[x].t, mi[x].se, s[x]);
if (l == r) return ;
int mid = l+r>>;
debug(ls, l, mid);
debug(rs, mid+, r);
} # undef ls
# undef rs
}T; int main() {
n = getint();
for (int i=; i<=n; ++i) a[i] = getint();
T.build(, , n);
int Q, op, l, r, x; cin >> Q;
while(Q--) {
// T.debug(1, 1, n);
op = getint(), l = getint(), r = getint();
if(op == ) {
x = getint();
T.edt(, , n, l, r, x);
} else if(op == ) {
x = getint();
T.edtmax(, , n, l, r, x);
} else if(op == ) {
x = getint();
T.edtmin(, , n, l, r, x);
} else if(op == ) printf("%lld\n", T.gsum(, , n, l, r));
else if(op == ) printf("%d\n", T.gmax(, , n, l, r));
else printf("%d\n", T.gmin(, , n, l, r));
}
return ;
}
bzoj4695 最假女选手的更多相关文章
- BZOJ4695 最假女选手(势能线段树)
BZOJ题目传送门 终于体会到初步掌握势能分析思想的重要性了. 一开始看题,感觉套路还是很一般啊qwq.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...
- 2018.07.27 bzoj4695: 最假女选手(线段树)
传送门 线段树好题 支持区间加,区间取min" role="presentation" style="position: relative;"> ...
- [BZOJ4695]最假女选手:segment tree beats!
分析 segment tree beats!模板题. 看了gxz的博客突然发现自己写的mxbt和mnbt两个标记没用诶. 代码 #include <bits/stdc++.h> #defi ...
- bzoj4695 最假女选手(势能线段树/吉司机线段树)题解
题意: 已知\(n\)个数字,进行以下操作: \(1.\)给一个区间\([L,R]\) 加上一个数\(x\) \(2.\)把一个区间\([L,R]\) 里小于\(x\) 的数变成\(x\) \(3.\ ...
- bzoj 4695 最假女选手 吉利线段树
最假女选手 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 480 Solved: 118[Submit][Status][Discuss] Desc ...
- 【bzoj4695】最假女选手 线段树区间最值操作
题目描述 给定一个长度为 N 序列,编号从 1 到 N .要求支持下面几种操作:1.给一个区间[L,R] 加上一个数x 2.把一个区间[L,R] 里小于x 的数变成x 3.把一个区间[L,R] 里大于 ...
- 【bzoj4695】最假女选手
zcy的励志故事.jpg 傻逼zcy突然想立一个flag,写一个segment-tree-beats的题娱乐一下 于是他就想起了这道题. 他打算今晚写完 然后光是写他就写的头昏脑涨,还犯了询问写反这种 ...
- BZOJ4695:最假女选手
浅谈区间最值操作和历史最值问题:https://www.cnblogs.com/AKMer/p/10225100.html 题目传送门:https://lydsy.com/JudgeOnline/pr ...
- (WC2016模拟十一)【BZOJ4695】最假女选手
ps:好久没更博啦……这几天连着有模拟赛,等初赛前后休息的时候来疯狂补坑吧……顺便补一下前面的数论啥的? 题解: mdzz我场上写了个15分暴力长度跟标算差不多... 线段树大法好啊!这题听说很多人做 ...
随机推荐
- 接口文档管理工具-Postman、Swagger、RAP(转载)
接口文档管理工具-Postman.Swagger.RAP 转自:http://www.51testing.com/html/10/n-3715910.html 在项目开发测试中,接口文档是贯穿始终的. ...
- c#基类继承
[ 塔 · 第 三 条 约 定 ] 编写一个多边形作为基类(成员:定点数)抽象方法(子类实现):体积.边长 正三角形类:成员 边长 长方形类:成员 长宽 using System; using Sys ...
- lintcode-142-O(1)时间检测2的幂次
142-O(1)时间检测2的幂次 用 O(1) 时间检测整数 n 是否是 2 的幂次. 样例 n=4,返回 true; n=5,返回 false. 挑战 O(1) time 标签 比特位操作 思路 使 ...
- JS DOM视频相关的知识
1.实现点击a标签改变图片时,如果a的href属性有一个目标网址,但是点击又必须跳转到另外一张图,往往会最后跳转到目标网址,可以在onclick事件函数中加入ruturn false,阻止跳转到页面. ...
- MongoDB、ElasticSearch、Redis、HBase这四种热门数据库的优缺点及应用场景
MongoDB MongoDB是当今最火爆的NoSQL数据库.MongoDB最早在09年发布,算得上是早期大数据时代的数据库代表作了.随着MongoDB的火爆,研发MongoDB的团队还专门成立了Mo ...
- tcp发送缓冲区中的数据都是由产生数据的进程给推送到ip层还是有定时任务触发?
和几个变量有非常大的关系 发送缓冲区的大小,如何单独设置一个socket的发送缓冲区 socketopt 发送缓冲区中的数据,如果被拥塞窗口限制住了,那么这些数据可能就放在tcpbuffer里的,此时 ...
- mysql表、函数等被锁住无响应的问题
场景: 在对表或函数等进行操作的时候,如果出现无法响应的情况(排除外网的网络问题),此时极有可能被某一个线程锁定了(这是函数的情况,表的话可能是被某一个用户锁定了),锁定的原因一般都是死循环出不来,而 ...
- 【poj2104】K-th Number 主席树
题目描述 You are working for Macrohard company in data structures department. After failing your previou ...
- Android命名格式化详解
严格换行 一般情况下一个“:”一换行 建议函数的“{}”分别占一行 例:public void ooSomething() { …… } 不要用: 例:public void doSomething ...
- Windows7上安装Git
我首先是百度到了这个网站:https://git-scm.com/download/win 这个网站上有下载链接,你可以根据你的系统选择不同的下载链接,我的是Win7 x64位的,下载地址为: htt ...