联赛模拟测试20 C. Weed
题目描述
\(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的更多相关文章
- [考试反思]0813NOIP模拟测试20
咕了两天,补一下. 4个AK的,210是第10,190的第15并列一大排,我个傻子160排第29. 历史新低,但是心态还好. 真是没想到会一天考两场.中午没回去睡觉晚上考试... 困倒是其次,关键还是 ...
- 8.10 NOIP模拟测试16 Blue+Weed+Drink
T1 Blue 贪心,每次跳得时候跳能跳到的最远的地方,跳过的就把他设为0,每次二分找到位置,一直跳就行,如果能跳到的位置就是当前位置或比当前位置还小(数组里现在呆着的这一块石头,二分得到的就是当前位 ...
- 联赛模拟测试10 C. 射手座之日
题目描述 分析 方法一(线段树) 线段树维护的是以当前节点为左端点的区间的贡献 而区间的右端点则会从 \(1\) 到 \(n\) 逐渐右移 当我们把右端点从 \(i-1\) 的位置扩展到 \(i\) ...
- 联赛模拟测试17 A. 简单的区间 启发式合并
题目描述 分析 我们要找的是一段区间的和减去该区间的最大值能否被 \(k\) 整除 那么对于一段区间,我们可以先找出区间中的最大值 然后枚举最大值左边的后缀与最大值右边的前缀之和是否能被 \(k\) ...
- 联赛模拟测试18 A. 施工 单调队列(栈)优化DP
题目描述 分析 对于 \(Subtask\ 1\),可以写一个 \(n^3\) 的 \(DP\),\(f[i][j]\) 代表第 \(i\) 个建筑高度为 \(j\) 时的最小花费,随便转移即可 时间 ...
- 联赛模拟测试24 B. 答题 折半枚举
题目描述 分析 暴力的思想是把 \(2^n\) 种得分枚举出来,每一种得分的概率都是相同的,然后从小到大累加,直到大于等于所给的概率 把问题转化一下,就变成了在 \(2^n\) 种元素中求 \(k\) ...
- noip模拟测试20
考试总结:这次考试,我非常真实地感觉到了自己能力的提高,具体来说,在之前的考试中,读完题之后我只会想到暴力的思路,甚至有的题连暴力都打不出来,但是这次在考场上我已经有了自己的一些想法,有了一个深入思考 ...
- 联赛模拟测试5 涂色游戏 矩阵优化DP
题目描述 分析 定义出\(dp[i][j]\)为第\(i\)列涂\(j\)种颜色的方案数 然后我们要解决几个问题 首先是求出某一列涂恰好\(i\)种颜色的方案数\(d[i]\) 如果没有限制必须涂\( ...
- 联赛模拟测试8 Dash Speed 线段树分治
题目描述 分析 对于测试点\(1\).\(2\),直接搜索即可 对于测试点\(3 \sim 6\),树退化成一条链,我们可以将其看成序列上的染色问题,用线段树维护颜色相同的最长序列 对于测试点\(7\ ...
随机推荐
- goto 语法在 PHP 中的使用
在C++.Java及很多语言中,都存在着一个神奇的语法,就是goto.顾名思义,它的使用是直接去到某个地方.从代码的角度来说,也就是直接跳转到指定的地方.PHP中也有这个功能,我们先来看看它是如何使用 ...
- 在windows下使用pip安装python包遇到缺失stdint.h文件的错误
今天在windows上使用pip安装一个python包python-lzf时遇到如下的错误: fatal error C1083: Cannot open include file: 'stdint. ...
- ServletContex对象学习
问题: 不同的用户使用相同的数据 解决: ServletContext对象 特点: 服务器创建 用户共享 作用域: 整个项目内 生命周期: 服务器启动到服务器关闭 使用: 1.获取SercvletCo ...
- Focal loss论文解析
Focal loss是目标检测领域的一篇十分经典的论文,它通过改造损失函数提升了一阶段目标检测的性能,背后关于类别不平衡的学习的思想值得我们深入地去探索和学习.正负样本失衡不仅仅在目标检测算法中会出现 ...
- Java知识系统回顾整理01基础03变量09块
一.定义 块:从{ 开始 到对应的} 结束,即一个块 public class HelloWorld { //类对应的块 public static void main(String[] args) ...
- __declspec(dllexport)和__declspec(dllimport) (——declspec方法创建dll的方法已验证ok)
转载:https://www.cnblogs.com/chengbing2011/p/4084125.html __declspec(dllimport)和__declspec(dllexport)经 ...
- ASP。NET Core路到微服务第01部分:构建视图
下载Part 1 source - 2.9 MB 介绍 说,如果你觉得有点失望找不到任何实际microservices在这篇文章中,这是因为有很多科目我想盖,它不可能谈论他们所有人(或讨论的多)在一篇 ...
- Windows7 提示“无法访问 xxxx,您没有权限访问,请与网络管理员联系请求访问权限”的解决办法
Windows7 客户端访问提示"无法访问 xxxx,您没有权限访问,请与网络管理员联系请求访问权限"的解决办法
- java -inally转
1.不管有木有出现异常,finally块中代码都会执行: 2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没有返 ...
- linux网络收包过程
记录一下linux数据包从网卡进入协议栈的过程,不涉及驱动,不涉及其他层的协议处理. 内核是如何知道网卡收到数据的,这就涉及到网卡和内核的交互方式: 轮询(poll):内核周期性的检查网卡,查看是否收 ...