题目描述

\(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. Erlang+RabbitMQ Server的详细安装

    Erlang(['ə:læŋ])是一种通用的面向并发的编程语言, 它有瑞典电信设备制造商爱立信所辖的CS-Lab开发,目的是创造一种可以应对大规模并发活动的编程语言和运行环境. Erlang官网:ht ...

  2. 提权 EXP

    windows: 漏洞列表 #Security Bulletin #KB #Description #Operating System CVE-2017-0213 [Windows COM Eleva ...

  3. mysql 空值(null)和空字符('')的区别

    日常开发中,一般都会涉及到数据库增删改查,那么不可避免会遇到Mysql中的NULL和空字符. 空字符(")和空值(null)表面上看都是空,其实存在一些差异: 定义: 空值(NULL)的长度 ...

  4. 决策树防止过拟合(预剪枝(Pre-Pruning))

    预剪枝(Pre-Pruning):预剪枝就是在构造决策树的过程中,先对每个结点在划分前进行估计,若果当前结点的划分不能带来决策树模型泛华性能的提升,则不对当前结点进行划分并且将当前结点标记为叶结点.

  5. hosts文件的内容

    C:\Windows\System32\drivers\etc\hosts 1 # Copyright (c) 1993-2009 Microsoft Corp. 2 # 3 # This is a ...

  6. PADS Layout VX.2.3 灌铜之后只显示灌铜外框,没有显示整块铜皮

    操作系统:Windows 10 x64 工具1:PADS Layout VX.2.3 使用Copper Pour功能,画了一个灌铜区,并分配了网络. Tools > Pour Manager,打 ...

  7. JavaScript格式化返回当前日期和时间

    要求: 返回当前日期和时间,如 2020年10月06日 星期二 下午08点15分35秒 代码实现: function getDate() { var date = new Date(); var ye ...

  8. 安装haproxy

    安装依赖 yum install -y gcc pcre pcre-devel openssl openssl-devel 创建依赖账号,并禁止账号登录 useradd -M -s /sbin/nol ...

  9. Apple uses Multipath TCP

    http://blog.multipath-tcp.org/blog/html/2018/12/15/apple_and_multipath_tcp.html December 15, 2018 Ap ...

  10. Activiti6.0获取下一节点任务的心路历程

    在我的开发任务中,我被分配了一个像下一个节点审批人发送短信的任务,这个任务看起来非常的简单,但在开发过程中遇到了许多的坑,在这里进行记录,如果你想要快速知道结果,请看代码版本(3). 首先,就是获取下 ...