题目描述

\(duyege\) 的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹。

为了查出真相,\(duyege\) 准备修好电脑之后再进行一次金坷垃的模拟实验。

电脑上面有若干层金坷垃,每次只能在上面撒上一层高度为 \(v_i\)的金坷垃

或者除掉最新\(v_i\) 层(不是量)撒的金坷垃。如果上面只留有不足\(v_i\) 层金坷垃,那么就相当于电脑上面没有金坷垃了。

\(duyege\) 非常严谨,一开始先给你 \(m\) 个上述操作要你依次完成。

然后又对实验步骤进行了\(q\)次更改,每次更改都会改变其中一个操作为另外一个操作。

每次修改之后都会询问最终金坷垃的量有多少。

输入格式

输入第一行为两个正整数\(m\)、\(q\) ,接下来 \(m\) 行每行\(2\) 个整数 \(k\)、\(v_i\) 。 \(k\)为 \(0\)时撒金坷垃,为\(1\) 时除金坷垃。

接下来\(q\) 行每行\(3\) 个整数 \(c_i\)、\(k\) 、\(v_i\) , 代表被更改的操作是第 \(c_i\) 个,

后面\(2\)个数描述更改为这样的操作。

输出格式

输出\(q\)行代表每次金坷垃的量为多少

样例

样例输入

10 5

0 10

1 5

0 13

0 18

0 2

1 1

0 8

0 9

1 3

0 7

9 0 3

10 1 7

6 0 8

10 0 5

8 1 2

样例输出

58

0

0

66

41

数据范围与提示

对于 \(30\%\)的数据,\(m \leq 1000,q \leq 1000\)

.

对于另外 \(20\%\) 的数据,每次\(k=1\) 时都会将金坷垃清空。

对于 100%的数据,\(m \leq 2 \times 10^5,q \leq 2 \times 10^5,v_i \leq 10^4\) .

分析

考场上 \(20\) 分暴力打挂,只因一个 \(continue\)

for(rg int i=1;i<=q;i++){
aa=read(),bb=read(),cc=read();
if(b[aa].op==0){
if(bb==0){
ad(aa,-b[aa].val);
ad(aa,cc);
} else {
now=cx(aa)-cx(aa-1);
ad(aa,-now);
xg(1,aa,aa);
}
} else {
if(bb) continue;
else {
xg(1,aa,0);
ad(aa,cc);
}
}
b[aa].op=bb,b[aa].val=cc;
now=shu[1].mmin;
if(now==0) printf("%d\n",cx(m));
else printf("%d\n",cx(m)-cx(now));
}
for(rg int i=1;i<=q;i++){
aa=read(),bb=read(),cc=read();
if(b[aa].op==0){
if(bb==0){
ad(aa,-b[aa].val);
ad(aa,cc);
} else {
now=cx(aa)-cx(aa-1);
ad(aa,-now);
xg(1,aa,aa);
}
} else {
if(!bb) {
xg(1,aa,0);
ad(aa,cc);
}
}
b[aa].op=bb,b[aa].val=cc;
now=shu[1].mmin;
if(now==0) printf("%d\n",cx(m));
else printf("%d\n",cx(m)-cx(now));
}

正解用线段树维护

每个点记录三个值:执行完这段操作后会删多少个,再插多少个,插的和一共是多少

合并值时再用一个函数查找左孩子被从右删除若干个后剩下的插入总和是多少

注意查找时,如果右儿子的层数大于清除的层数

应该写成

return tr[da].sum-tr[da<<1|1].sum+cx(da<<1|1,cnt);

而不是

return tr[da<<1].sum+cx(da<<1|1,cnt);

比如这样的数据('-'代表删除)

++++ -+++

代码

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define rg register
inline int read(){
rg int x=0,fh=1;
rg char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*fh;
}
const int maxn=1e6+5;
int m,q;
struct asd{
int op,val;
asd(){}
asd(int aa,int bb){
op=aa,val=bb;
}
}b[maxn];
struct trr{
int l,r,sum,cnt,del;
}tr[maxn];
int cx(int da,int cnt){
if(tr[da<<1|1].cnt==cnt){
return tr[da].sum-tr[da<<1|1].sum;
} else if(tr[da<<1|1].cnt>cnt){
return tr[da].sum-tr[da<<1|1].sum+cx(da<<1|1,cnt);
} else {
return cx(da<<1,cnt-tr[da<<1|1].cnt+tr[da<<1|1].del);
}
}
void push_up(int da){
if(tr[da<<1|1].del>tr[da<<1].cnt){
tr[da].del=tr[da<<1].del+tr[da<<1|1].del-tr[da<<1].cnt;
tr[da].cnt=tr[da<<1|1].cnt;
tr[da].sum=tr[da<<1|1].sum;
} else if(tr[da<<1|1].del==0){
tr[da].del=tr[da<<1].del;
tr[da].sum=tr[da<<1].sum+tr[da<<1|1].sum;
tr[da].cnt=tr[da<<1].cnt+tr[da<<1|1].cnt;
} else {
tr[da].del=tr[da<<1].del;
tr[da].cnt=tr[da<<1].cnt+tr[da<<1|1].cnt-tr[da<<1|1].del;
if(tr[da<<1].cnt==tr[da<<1|1].del) tr[da].sum=tr[da<<1|1].sum;
else tr[da].sum=tr[da<<1|1].sum+cx(da<<1,tr[da<<1|1].del);
}
}
void build(int da,int l,int r){
tr[da].l=l,tr[da].r=r;
if(tr[da].l==tr[da].r){
if(b[l].op==1){
tr[da].del=b[l].val;
} else {
tr[da].cnt=1;
tr[da].sum=b[l].val;
}
return;
}
rg int mids=(tr[da].l+tr[da].r)>>1;
build(da<<1,l,mids);
build(da<<1|1,mids+1,r);
push_up(da);
}
void xg(int da,int wz){
if(tr[da].l==tr[da].r){
if(b[wz].op==1){
tr[da].del=b[wz].val;
tr[da].cnt=tr[da].sum=0;
} else {
tr[da].del=0;
tr[da].cnt=1;
tr[da].sum=b[wz].val;
}
return;
}
rg int mids=(tr[da].l+tr[da].r)>>1;
if(wz<=mids) xg(da<<1,wz);
else xg(da<<1|1,wz);
push_up(da);
}
int main(){
freopen("weed.in","r",stdin);
freopen("weed.out","w",stdout);
m=read(),q=read();
for(rg int i=1;i<=m;i++){
b[i].op=read(),b[i].val=read();
}
build(1,1,m);
rg int aa,bb,cc;
for(rg int i=1;i<=q;i++){
aa=read(),bb=read(),cc=read();
b[aa].op=bb,b[aa].val=cc;
xg(1,aa);
printf("%d\n",tr[1].sum);
}
return 0;
}

联赛模拟测试20 C. Weed的更多相关文章

  1. [考试反思]0813NOIP模拟测试20

    咕了两天,补一下. 4个AK的,210是第10,190的第15并列一大排,我个傻子160排第29. 历史新低,但是心态还好. 真是没想到会一天考两场.中午没回去睡觉晚上考试... 困倒是其次,关键还是 ...

  2. 8.10 NOIP模拟测试16 Blue+Weed+Drink

    T1 Blue 贪心,每次跳得时候跳能跳到的最远的地方,跳过的就把他设为0,每次二分找到位置,一直跳就行,如果能跳到的位置就是当前位置或比当前位置还小(数组里现在呆着的这一块石头,二分得到的就是当前位 ...

  3. 联赛模拟测试10 C. 射手座之日

    题目描述 分析 方法一(线段树) 线段树维护的是以当前节点为左端点的区间的贡献 而区间的右端点则会从 \(1\) 到 \(n\) 逐渐右移 当我们把右端点从 \(i-1\) 的位置扩展到 \(i\) ...

  4. 联赛模拟测试17 A. 简单的区间 启发式合并

    题目描述 分析 我们要找的是一段区间的和减去该区间的最大值能否被 \(k\) 整除 那么对于一段区间,我们可以先找出区间中的最大值 然后枚举最大值左边的后缀与最大值右边的前缀之和是否能被 \(k\) ...

  5. 联赛模拟测试18 A. 施工 单调队列(栈)优化DP

    题目描述 分析 对于 \(Subtask\ 1\),可以写一个 \(n^3\) 的 \(DP\),\(f[i][j]\) 代表第 \(i\) 个建筑高度为 \(j\) 时的最小花费,随便转移即可 时间 ...

  6. 联赛模拟测试24 B. 答题 折半枚举

    题目描述 分析 暴力的思想是把 \(2^n\) 种得分枚举出来,每一种得分的概率都是相同的,然后从小到大累加,直到大于等于所给的概率 把问题转化一下,就变成了在 \(2^n\) 种元素中求 \(k\) ...

  7. noip模拟测试20

    考试总结:这次考试,我非常真实地感觉到了自己能力的提高,具体来说,在之前的考试中,读完题之后我只会想到暴力的思路,甚至有的题连暴力都打不出来,但是这次在考场上我已经有了自己的一些想法,有了一个深入思考 ...

  8. 联赛模拟测试5 涂色游戏 矩阵优化DP

    题目描述 分析 定义出\(dp[i][j]\)为第\(i\)列涂\(j\)种颜色的方案数 然后我们要解决几个问题 首先是求出某一列涂恰好\(i\)种颜色的方案数\(d[i]\) 如果没有限制必须涂\( ...

  9. 联赛模拟测试8 Dash Speed 线段树分治

    题目描述 分析 对于测试点\(1\).\(2\),直接搜索即可 对于测试点\(3 \sim 6\),树退化成一条链,我们可以将其看成序列上的染色问题,用线段树维护颜色相同的最长序列 对于测试点\(7\ ...

随机推荐

  1. RabbitMQ消息积压的几种解决思路

    在日常工作中使用RabbitMQ偶尔会遇不可预料的情况导致的消息积压,一般出现消息积压基本上分为几种情况: 消费者消费消息的速度赶不上生产速度,这总问题主要是业务逻辑没设计好消费者和生产者之间的平衡, ...

  2. Java虚拟机栈--栈帧

    栈帧的内部结构 每个栈帧中存储着 1.局部变量表(Local Variables) 2.操作数栈(Operand Stack)(或表达式栈) 3.动态链接(Dynamic Linking)(或执行&q ...

  3. mariadb 1

    mariadb(第一章)     数据库介绍 1.什么是数据库? 简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织,存储的,我们 ...

  4. netty之bootstrap

    转载自https://blog.csdn.net/zxhoo/article/details/17419229 Netty4学习笔记(2)-- Bootstrap Netty4的代码比我想象的要复杂的 ...

  5. 新手接触springboot

    新手使用springboot或者说,刚接触java行业,有些不明白的就是项目的架构是怎么样的,我今天在这儿稍微整理了一下 有些新手可能在想,springboot是怎么解决最原始的增-删-改-查, 快速 ...

  6. python的多种魔术方法

    目录 new str & repr iter getitem.setitem.delitem getattr.setattr.delattr call slots 定制类和魔法方法 new s ...

  7. SpringBoot框架:两个方法同时调用时父方法使内部方法的DataSource注解失效的解决办法

    一.问题如下: 使用的是SpringBoot框架:通过AOP和自定义注解完成druid连接池的动态数据源切换(三)中的两个数据库spring_boot_demo和other_data. 在UserCo ...

  8. Python-字符编码-Unicode UTF-8

    什么是字符编码? --世界上有很多国家,每个国家都有自己独特的语言,所以在计算机普及的当今世界, 每个国家都有自己的字符编码,本国的软件运行在其他国家的机器上,会出现乱码, 有utf-8,gbk等各种 ...

  9. Mac系统下的zip压缩包解压到Windows下出现乱码的解决方法

    环境变量 环境变量是具有特殊名字的一个特定对象,包含了一个或多个应用程序运行所需的信息.(例如PATH,可执行程序的搜索路径,当要求系统运行一个程序,而没告诉系统它的具体路径时,系统就要在PTAH值的 ...

  10. C++枚举变量与switch

    转载:https://www.cnblogs.com/banmei-brandy/p/11263927.html 枚举类型和变量如何定义,下篇博客讲得十分详细: https://blog.csdn.n ...