hdu6521 吉司机线段树】的更多相关文章

http://acm.hdu.edu.cn/showproblem.php?pid=6521 待填 代码 #include<bits/stdc++.h> #define ls o<<1 #define rs o<<1|1 #define ll long long using namespace std; const int MAXN = 5e5+5; int Mx[MAXN<<2],Mx2[MAXN<<2],Mn[MAXN<<2],l…
题目链接 吉司机线段树裸题... #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f3f3f3f3f; ll n,m,a[N],mx[N<<],se[N<<],nmx[N<<],lz[N<<]; ll sum[N<<]; #define ls (u<<1) #define rs (u<<1|1) #…
题目链接 题意:在一条直线上依次建造n座建筑物,每座建筑物建造完成后询问它在多长的部分是最高的. 比较好想的方法是用线段树分别维护每个区间的最小值mi和最大值mx,当建造一座高度为x的建筑物时,若mi>x则答案无贡献,直接退出,若mx<=x则区间赋值为x,答案加上区间长度.其他情况需要继续递归搜索. #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f; ],mi[N&l…
题意 题目链接 Sol 传说中的吉司机线段树??感觉和BZOJ冒险那题差不多,就是强行剪枝... 这题最坑的地方在于对于操作1,$C >= 0$, 操作2中需要对0取max,$a[i] >= 0$,这不就是统计最小值出现的次数么?? 按照套路 维护好区间赋值标记 / 区间加法标记 / 区间max标记 / 区间最小值 / 区间最小值出现的次数 / 区间次小值 对于第二个操作就拆成区间加 和 区间max 区间max是一个很神奇的操作 设当前加入的数为val 若val>=mn,那该操作对该区间…
题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 赋值为\(x\) \(2.\)区间\([L,R]\) 赋值为\(max(a[i] + x, 0)\) \(3.\)区间\([L,R]\) 询问\(0\)个数 已知初始值\(\geq 0\),\(x\geq0\). 思路: 吉司机线段树. 操作\(1\)可以直接打覆盖标记. 操作\(2\)可以分为两步:区间加\(x\),然后取区间\(max(a[i],0)\). 操作\(3\)只要维护最小值的个数,因为不管怎么操作最…
题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 按位与\(x\) \(2.\)区间\([L,R]\) 按位或\(x\) \(3.\)区间\([L,R]\) 询问最大值 思路: 吉司机线段树. 我们按位考虑,维护区间或\(\_or\)和区间与\(\_and\),那么得到区间非公有的\(1\)为\((\_or \oplus \_and)\),那么如果对所有的非公有的\(1\)影响都一样就不会对最大值有影响,那么就直接打标机,否则继续往下更新.即 \[[(\_or[r…
题意: 已知\(n\)个数字,进行以下操作: \(1.\)给一个区间\([L,R]\) 加上一个数\(x\) \(2.\)把一个区间\([L,R]\) 里小于\(x\) 的数变成\(x\) \(3.\)把一个区间\([L,R]\) 里大于\(x\) 的数变成\(x\) \(4.\)求区间\([L,R]\)的和 \(5.\)求区间\([L,R]\)的最大值 \(6.\)求区间\([L,R]\) 的最小值 思路: 吉司机线段树. 假如我们要进行把一个区间\([L,R]\) 里小于\(x\) 的数变成…
题意:给出a,b数组,区间上两种操作,给\(a[L,R]\)+1s,或者求\(\sum_{i=l}^{r}a_i/b_i\) 一看就知道是吉司机乱搞型线段树(低配版),暴力剪枝就好 维护区间a的最大值和b的最小值,如果存在相交的部分则证明可能产生新的贡献, 此时暴搜到叶子把可能的a置回0并加上贡献就好 然后疯狂TTTT 网上搜了一波题解好像说是会改变lazy的判断?(虽然觉得没有道理但是我认(怂)了 于是换一种策略,既然lazy依赖与a的最值,那我们尽量不碰它,改为b的值翻倍 然后过了 算学到了…
思路: 后面nlogn的部分是伪证... 大家可以构造数据证明是这是nlog^2n的啊~ 吉老司机翻车了 //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; ; int cases,n,m,op,xx,yy,zz; typedef long long ll; ]; void push_up(int pos){ tr[pos].max2=;,rson=pos<<|; tr[p…
题意:给你一个序列,需要支持以下操作:1:区间内的所有数加上某个值.2:区间内的所有数除以某个数(向下取整).3:询问某个区间内的最大值. 思路(从未见过的套路):维护区间最大值和区间最小值,执行2操作时,继续向下寻找子区间,如果区间满足:min - (min / x) == max - (max / x)时,给这个区间内的所有数减去min - (min / x)就可以了.为什么这样做呢?因为向下取整操作变化速度远快于加法,在经过很多次操作后其实序列中的数区域相等,复杂度需要用势能分析之类的,均…