观察复杂度,是log级别以下回答询问的。

O(1)?逗我kx呢?

自然而然地想到线段树。

学长讲的原题啊考场上还不会打。

线段树上的每个节点都表示一个操作区间。

线段树上维护的权值有3个:这个子区间一共“净”加了多少层cnt,多少量num,以及它需要除掉前面的多少层del。

因为对于每一个子区间,它只可能有几种情况:

新累加了几层,或者这个子区间不够删了删前面的几层,或先删掉前面的几层再加上新的几层。

那么每个叶节点就不用说啦,关键就在于两个区间合并。

1,如果右区间要删左区间而且还能把它删干净,那么整个区间要删的量就是del[r]+del[l]-cnt[l],整个区间累加的量就是右区间所累加的

2,如果删了但没删干净,那么我们就需要删掉左区间里最靠后的几个没被删除的值,删除量就是左区间的删除量,剩余层数就是cnt[l]+cnt[r]-del[r]

但是怎么知道那“最靠后的几个值”呢?

稍微改变一下设问,查询线段树子树中区间内最后几个有权值位置的权值和。打个ask函数就好了。

然而这里有一个易错点:你不能直接查询左子树的最靠后的那几个值,因为右子树可能删除了它的一部分。

所以你要查询的是p子树的后k个的话,实际上就是ask(p,k+del[bro])-ask(p,del[bro])

bro是指p的右兄弟。如果p本身就是右子树则不存在。这样被它右子树删除的元素就被我们考虑到了。

然后就到了考验码力的时候了。

 #include<bits/stdc++.h>
using namespace std;
#define lc p<<1
#define rc p<<1|1
int opt[],k[],num[],cnt[],del[],n,m,cl[],cr[];
int ask(int p,int t){
if(!t)return ;
if(cnt[p]<=t)return num[p];
if(t<=cnt[rc])return ask(rc,t);
return ask(lc,t-cnt[rc]+del[rc])-ask(lc,del[rc])+num[rc];
}
void up(int p){
if(del[rc]>cnt[lc])del[p]=del[lc]+del[rc]-cnt[lc],cnt[p]=cnt[rc],num[p]=num[rc];
else del[p]=del[lc],cnt[p]=cnt[rc]+cnt[lc]-del[rc],num[p]=num[rc]+num[lc]-ask(lc,del[rc]);
}
void build(int p,int l,int r){
cl[p]=l;cr[p]=r;
if(l==r){
if(opt[l])del[p]=k[l];
else cnt[p]=,num[p]=k[l];
return;
}
build(lc,l,l+r>>);build(rc,(l+r>>)+,r);up(p);
}
void change(int p,int x){
if(cl[p]==cr[p]){
if(opt[x])del[p]=k[x],cnt[p]=num[p]=;
else cnt[p]=,num[p]=k[x],del[p]=;
return;
}
if(cl[rc]<=x)change(rc,x);else change(lc,x);up(p);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)scanf("%d%d",&opt[i],&k[i]);
build(,,n);
for(int i=,x;i<=m;++i){
scanf("%d",&x);scanf("%d%d",&opt[x],&k[x]);
change(,x);printf("%d\n",num[]);
}
}

就1.1k但都是精华

Weed:线段树的更多相关文章

  1. 【Foreign】Weed [线段树]

    Weed Time Limit: 20 Sec  Memory Limit: 512 MB Description 从前有个栈,一开始是空的. 你写下了 m 个操作,每个操作形如 k v : 若 k ...

  2. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  3. 【模拟8.10】Weed(线段树)

    考试只好随便骗骗分过去啦啦啦..... 正解是玄学线段树: 以每个操作为叶子节点,我们定义几个变量ce表示层数,h表示高度,add表示所减的层数 那么问题转化为单点修改的问题输出直接是根节点答案 但是 ...

  4. [CSP-S模拟测试]:Weed(线段树)

    题目描述 $duyege$的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹.为了查出真相,$duyege$准备修好电脑之后再进行一次金坷垃的模拟实验.电脑上面有若干层金坷垃,每次只能在上面撒上一层高度 ...

  5. bzoj3932--可持久化线段树

    题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...

  6. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  7. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  8. codevs 1080 线段树点修改

    先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...

  9. codevs 1082 线段树区间求和

    codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...

随机推荐

  1. B/S 工业互联网 地铁行业

    前言 近几年,互联网与交通运输的融合,改变了交易模式,影响着运输组织和经营方式,改变了运输主体的市场结构.模糊了运营与非营运的界限,也更好的实现了交通资源的集约共享,同时使得更多依靠外力和企业推动交通 ...

  2. (4)一起来看下mybatis框架的缓存原理吧

    本文是作者原创,版权归作者所有.若要转载,请注明出处.本文只贴我觉得比较重要的源码,其他不重要非关键的就不贴了 我们知道.使用缓存可以更快的获取数据,避免频繁直接查询数据库,节省资源. MyBatis ...

  3. 问题TypeError: __init__() takes 1 positional argument but 2 were given解决方案

    在搭建自动化框架时,遇到一个问题,如下图: 根据报错的意思,应该是__init__函数的问题, 位置应该是HomePage文件 立马去查看一下文件,如图: 原来是因为的粗心大意__init__(sel ...

  4. 落谷P3941 入阵曲

    题目背景 pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv 丹青千秋酿,一醉解愁肠. 无悔少年枉,只愿壮志狂. 题目描述 小 F 很喜欢数学,但是到 ...

  5. CVE-2019-0708(非蓝屏poc)远程桌面代码执行漏洞复现

    玩了几天 刚回成都  玩电脑复现一下~ 内核漏洞原理暂时 没看懂 别问 ,问就是不懂 0x01 复现环境和Exp准备 漏洞影响范围 Windows 7 Windows Server 2008 R2 W ...

  6. 为什么要学3D建模呢?你看中的肯定是这几点

    游戏行业的大环境 互联网的形态一直以来都是2D模式的,但是随着3D技术的不断进步,在未来的5年时间里,将会有越来越多的互联网应用以3D的方式呈现给用户,包括网络视讯.电子阅读.虚拟社区.网络游戏.电子 ...

  7. java学习3-流程控制与数组

    1.顺序结构 2.分支结构 3.循环结构 4.控制循环结构 break continue return 5.数组

  8. Linux面试题-8

    1.Linux文件系统的文件都按其作用分门别类地放在相关的目录中,对于磁盘这种外部设备文件,一般应将其放在(C)目录中. A./bin B./etc C./dev D./lib 2.当使用mount进 ...

  9. Open vSwitch系列之一 Open vSwitch诞生

    Open vSwitch系列之一 Open vSwitch诞生 Open vSwitch系列之二 安装指定版本ovs 2006年,SDN诞生于美国GENI项目资助的斯坦福大学Clean Slate课题 ...

  10. 百万年薪python之路 -- 闭包

    2.闭包 闭包的定义: 闭包是嵌套在函数中的函数. 闭包必须是内层函数对外层函数的变量(非全局变量)的引用. 一句话定义就是:在嵌套函数内,对非全局变量 (且不是本层的变量)的引用 如何判断判断闭包? ...