BZOJ4355: Play with sequence(吉司机线段树)
题意
Sol
传说中的吉司机线段树??感觉和BZOJ冒险那题差不多,就是强行剪枝。。。
这题最坑的地方在于对于操作1,$C >= 0$, 操作2中需要对0取max,$a[i] >= 0$,这不就是统计最小值出现的次数么??
按照套路
维护好区间赋值标记 / 区间加法标记 / 区间max标记 / 区间最小值 / 区间最小值出现的次数 / 区间次小值
对于第二个操作就拆成区间加 和 区间max
区间max是一个很神奇的操作
设当前加入的数为val
若val>=mn,那该操作对该区间无影响
若se < val < mn,该操作只会对次小值产生影响,因为对其他的标记均不会产生影响,因此打一个额外的标记即可
否则暴力递归
时间复杂度:$O(n log^2n)$??
另外这东西可以做区间加 / 查询历史版本,前者维护一下标记就行,,后者嘛,,,等长大了再研究吧qwq
- #include<cstdio>
- #include<algorithm>
- #define LL long long
- //#define int long long
- using namespace std;
- const int MAXN = * 1e5 + ;
- const LL INF = 1e10 +;
- inline int read() {
- char c = getchar(); int x = , f = ;
- while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
- while(c >= '' && c <= '') x = x * + c - '', 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 << ];
- void update(int k) {
- //T[k].mn = min(T[ls].mn, T[rs].mn);
- if(T[ls].mn < T[rs].mn) T[k].cnt = T[ls].cnt, T[k].mn = T[ls].mn, T[k].se = min(T[rs].mn, T[ls].se);
- else if(T[ls].mn > T[rs].mn) T[k].cnt = T[rs].cnt, T[k].mn = T[rs].mn, T[k].se = min(T[ls].mn, T[rs].se);
- else T[k].cnt = T[ls].cnt + T[rs].cnt, T[k].mn = T[ls].mn, T[k].se = min(T[ls].se, T[rs].se);
- }
- void MemP(int k, LL val) {
- T[k].cov = val;
- T[k].cnt = T[k].siz;
- T[k].se = INF;
- T[k].Mx = -INF;
- T[k].add = ;
- T[k].mn = val;
- }
- void AddP(int k, LL val) {
- if(T[k].se != INF) T[k].se += val;
- if(T[k].Mx != -INF) T[k].Mx += val;
- T[k].mn += val;
- T[k].add += val;
- }
- void MaxP(int k, LL val) {
- T[k].mn = max(T[k].mn, val);//
- T[k].Mx = max(T[k].Mx, val);
- }
- void pushdown(int k) {
- if(T[k].cov != INF) MemP(ls, T[k].cov), MemP(rs, T[k].cov), T[k].cov = INF;
- if(T[k].add) AddP(ls, T[k].add), AddP(rs, T[k].add), T[k].add = ;
- if(T[k].Mx != -INF) MaxP(ls, T[k].Mx), MaxP(rs, T[k].Mx), T[k].Mx = -INF;
- }
- void Build(int k, int ll, int rr) {
- T[k] = (Node) {ll, rr, rr - ll + , , -INF, , , INF, INF};
- if(ll == rr) {
- T[k].mn = a[ll]; T[k].cnt = ;
- return ;
- }
- int mid = T[k].l + T[k].r >> ;
- Build(ls, ll, mid); Build(rs, mid + , rr);
- update(k);
- }
- void IntMem(int k, int ll, int rr, LL val) {
- if(ll <= T[k].l && T[k].r <= rr) {MemP(k, val); return ;}
- pushdown(k);
- int mid = T[k].l + T[k].r >> ;
- if(ll <= mid) IntMem(ls, ll, rr, val);
- if(rr > mid) IntMem(rs, ll, rr, val);
- update(k);
- }
- void IntAdd(int k, int ll, int rr, LL val) {
- if(ll <= T[k].l && T[k].r <= rr) {AddP(k, val); return ;}
- pushdown(k);
- int mid = T[k].l + T[k].r >> ;
- if(ll <= mid) IntAdd(ls, ll, rr, val);
- if(rr > mid) IntAdd(rs, ll, rr, val);
- update(k);
- }
- void IntMax(int k, int ll, int rr, LL val) {
- if(val <= T[k].mn) return ;
- if(ll <= T[k].l && T[k].r <= rr && T[k].se > val) {//tag
- MaxP(k, val);
- return ;
- }
- int mid = T[k].l + T[k].r >> ;
- pushdown(k);
- if(ll <= mid) IntMax(ls, ll, rr, val);
- if(rr > mid) IntMax(rs, ll, rr, val);
- update(k);
- }
- LL Query(int k, int ll, int rr) {
- // int ans = 0;
- if(ll <= T[k].l && T[k].r <= rr)
- return (T[k].mn == ? T[k].cnt : );
- pushdown(k);
- int mid = T[k].l + T[k].r >> ;
- if(ll > mid) return Query(rs, ll, rr);
- else if(rr <= mid) return Query(ls, ll, rr);
- else return Query(ls, ll, rr) + Query(rs, ll, rr);
- }
- main() {
- // freopen("4355.in", "r", stdin);
- // freopen("4355.out", "w", stdout);
- N = read(); Q = read();
- for(int i = ; i <= N; i++) a[i] = read();
- Build(, , N);
- while(Q--) {
- int opt = read(), l = read(), r = read(), val;
- if(opt == ) printf("%d\n", Query(, l, r));
- else {
- val = read();
- if(opt == ) IntMem(, l, r, val);
- else {
- IntAdd(, l, r, val);
- IntMax(, l, r, );
- }
- }
- }
- return ;
- }
BZOJ4355: Play with sequence(吉司机线段树)的更多相关文章
- HDU - 5306 Gorgeous Sequence (吉司机线段树)
题目链接 吉司机线段树裸题... #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3 ...
- bzoj4355 Play with sequence(吉司机线段树)题解
题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 赋值为\(x\) \(2.\)区间\([L,R]\) 赋值为\(max(a[i] + x, 0)\) \(3.\)区间 ...
- UVALive - 4108 SKYLINE (吉司机线段树)
题目链接 题意:在一条直线上依次建造n座建筑物,每座建筑物建造完成后询问它在多长的部分是最高的. 比较好想的方法是用线段树分别维护每个区间的最小值mi和最大值mx,当建造一座高度为x的建筑物时,若mi ...
- bzoj5312 冒险(吉司机线段树)题解
题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 按位与\(x\) \(2.\)区间\([L,R]\) 按位或\(x\) \(3.\)区间\([L,R]\) 询问最大值 ...
- bzoj4695 最假女选手(势能线段树/吉司机线段树)题解
题意: 已知\(n\)个数字,进行以下操作: \(1.\)给一个区间\([L,R]\) 加上一个数\(x\) \(2.\)把一个区间\([L,R]\) 里小于\(x\) 的数变成\(x\) \(3.\ ...
- HDU - 6315 吉司机线段树
题意:给出a,b数组,区间上两种操作,给\(a[L,R]\)+1s,或者求\(\sum_{i=l}^{r}a_i/b_i\) 一看就知道是吉司机乱搞型线段树(低配版),暴力剪枝就好 维护区间a的最大值 ...
- HDU 5306 吉司机线段树
思路: 后面nlogn的部分是伪证... 大家可以构造数据证明是这是nlog^2n的啊~ 吉老司机翻车了 //By SiriusRen #include <cstdio> #include ...
- hdu6521 吉司机线段树
http://acm.hdu.edu.cn/showproblem.php?pid=6521 待填 代码 #include<bits/stdc++.h> #define ls o<& ...
- Petrozavodsk Winter-2018. AtCoder Contest. Problem I. ADD, DIV, MAX 吉司机线段树
题意:给你一个序列,需要支持以下操作:1:区间内的所有数加上某个值.2:区间内的所有数除以某个数(向下取整).3:询问某个区间内的最大值. 思路(从未见过的套路):维护区间最大值和区间最小值,执行2操 ...
随机推荐
- 02_android下单元测试
Java的单元测试JUnit. Java程序入口是main方法.一般不在安卓程序入口 @Override protected void onCreate(Bundle savedInstanceSta ...
- [xdoj1029]求解某个数的最高位和最低位
解题关键: 1.最高位求法 long long int x=n^m; 式子两边同时取lg lg(x)=m*lg(n): x=10^(m*lg(n)): 10的整数次方的最高位一定是1,所以x的最高位取 ...
- Jmeter分布式测试需要注意事项
Jmeter分布式测试需要注意事项: 1. 如果脚本中有用到CSV Data Set Config,则所有的模拟机都必须在相应的目录下存在该文件.如下图,则必须所有模拟机的F盘下都有user.txt文 ...
- R:安装、导入各种包。
library和require都可以载入包,但二者存在区别. #在一个函数中,如果一个包不存在,执行到library将会停止执行,require则会继续执行.require将会根据包的存在与否返回tr ...
- iOS开发,在main thread以外的thread更新UI
如果需要在异步任务(Async Task)中更新UI,若直接设置UI,会导致程序崩溃. 例如,在异步block中去更改UI: NSOperationQueue *queue=[[NSOperation ...
- 25. CTF综合靶机渗透(17)
靶机链接 https://www.vulnhub.com/entry/the-ether-evilscience,212 运行环境 本靶机提供了VMware的镜像,从Vulnhub下载之后解压,运行v ...
- sql获取当日减去几天的几天前日期
CONVERT(varchar(10),DATEADD(DAY, -220 ,CONVERT(nvarchar(10),getdate(),23)),23)
- SqlServer(带中文注释)
using System;using System.Data;using System.Xml;using System.Data.SqlClient;using System.Collections ...
- React 从入门到进阶之路(三)
之前的文章我们介绍了 React 创建组件.JSX 语法.绑定数据和绑定对象.接下来我们将介绍 React 绑定属性( 绑定class 绑定style).引入图片 循环数组渲染数据. 上一篇中我们 ...
- 配置OpenCV报应用程序无法正常启动0xc000007b
我的配置软件是OpenCV3.4.1和visual studio2017.参考这篇博客(https://blog.csdn.net/qq_41175905/article/details/805604 ...