20161003 NOIP 模拟赛 T2 解题报告
Weed
duyege的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹。
为了查出真相,duyege 准备修好电脑之后再进行一次金坷垃的模拟实验。
电脑上面有若干层金坷垃,每次只能在上面撒上一层高度为 vi 的金坷垃,或者除掉最 新 vi 层(不是量)撒的金坷垃。如果上面只留有不足 vi 层金坷垃,那么就相当于电脑上 面没有金坷垃了。
duyege 非常严谨,一开始先给你 m 个上述操作要你依次完成。然后又对实验步骤进行 了 q 次更改,每次更改都会改变其中一个操作为另外一个操作。每次修改之后都会询问最 终金坷垃的量有多少。
输入第一行为两个正整数 m、q,接下来 m 行每行 2 个整数 k、vi。k 为 0 时撒金坷垃, 为 1 时除金坷垃。接下来 q 行每行 3 个整数 ci、k、vi,ci 代表被更改的操作是第 ci 个, 后面 2 个数描述更改为这样的操作。 输出 q 行代表每次金坷垃的量为多少
对于 30%的数据,m<=1000,q<=1000.
对于另外 20%的数据,每次 k=1 时都会将金坷垃清空。
对于 100%的数据,m<=2*10^5,q<=2*10^5,vi<=10^4.
——————————————分割线——————————————
分析:
( 30分 )这道题朴素想法是每次对某个操作修改,然后依次算到最后一个元素。
( 100分 )朴素的想法在逐个计算上耗时太多,这时我们需要一种数据结构,能够对某个操作修改,又能够对某一段查询,那么不难想到线段树。
我们需要维护三个信息,即当前区间中操作的金坷垃数量,层数,以及需要删去更左边操作的层数。
显然左边的删除操作不会影响之后的操作,那么我们只需要对每个节点进行结算,统计即可。
下面代码的Push_up函数比较难懂,特此注释。
#include "bits/stdc++.h"
#define Never return
#define Explode 0 using namespace std ;
struct SegTree { int l , r , Add , Cnt , Del ;};
const int maxN = 2e5 + ; SegTree tr[ maxN << ] ;
int arr[ maxN ] ;
bool op[ maxN ] ; int INPUT ( ) {
int x = , f = ;char ch = getchar( ) ;
while ( ch < '' || ch > '' ) { if( ch == '-' ) f= - ; ch = getchar( ) ; }
while ( ch >= '' && ch <= '' ) { x = ( x << ) + ( x << ) + ch - '' ; ch = getchar( ) ; }
return x * f ;
} int Query_Tree ( const int i , const int Target ) {
if ( Target == tr[ i << | ].Add ) {
return tr[ i ].Cnt - tr[ i << | ].Cnt ;
}
else if ( Target < tr[ i << | ].Add ) {
return tr[ i ].Cnt - tr[ i << | ].Cnt + Query_Tree ( i << | , Target ) ;
}
else {
return Query_Tree ( i << , Target - tr[ i << | ].Add + tr[ i << | ].Del ) ;
}
} void Push_up ( const int i ) {
int lchild = i << ;
int rchild = lchild + ;
if ( tr[ rchild ].Del >= tr[ lchild ].Add ) {//右区间 删除数大于等于左边层数
tr[ i ].Del = tr[ lchild ].Del + tr[ rchild ].Del - tr[ lchild ].Add ;
tr[ i ].Add = tr[ rchild ].Add ;
tr[ i ].Cnt = tr[ rchild ].Cnt ;
}
else if ( !tr[ rchild ].Del ) {//右区间没有删除
tr[ i ].Add = tr[ lchild ].Add + tr[ rchild ].Add ;
tr[ i ].Cnt = tr[ lchild ].Cnt + tr[ rchild ].Cnt ;
tr[ i ].Del = tr[ lchild ].Del ;
}
else {//右边无法全部删去左边
tr[ i ].Del = tr[ lchild ].Del ;
tr[ i ].Add = tr[ lchild ].Add + tr[ rchild ].Add - tr[ rchild ].Del ;
tr[ i ].Cnt = tr[ rchild ].Cnt + Query_Tree ( lchild , tr[ rchild ].Del ) ;
}
}
void Build_Tree ( const int x , const int y , const int i ) {
tr[ i ].l = x ;
tr[ i ].r = y ;
if ( x == y ) {
if ( op[ x ] ) tr[ i ].Del = arr[ x ] ;
else if ( !op[ x ] ) {
tr[ i ].Add = ;
tr[ i ].Cnt = arr[ x ] ;
}
}
else {
int mid = ( tr[ i ].l + tr[ i ].r ) >> ;
Build_Tree ( x , mid , i<< ) ;
Build_Tree ( mid + , y , i<<| ) ;
Push_up ( i ) ;
}
return ;
} void Update_Tree ( const int i , const int Target ) {
if ( tr[ i ].l == tr[ i ].r ) {
tr[ i ].Add = tr[ i ].Cnt = tr[ i ].Del = ;
if ( INPUT ( ) ) {
tr[ i ].Del = INPUT( ) ;
}
else {
tr[ i ].Cnt = INPUT ( ) ;
tr[ i ].Add = ;
}
}
else {
int mid = ( tr[ i ].l + tr[ i ].r ) >> ;
if ( Target > mid ) Update_Tree ( i << | , Target ) ;
else if( Target <= mid ) Update_Tree ( i << , Target ) ;
Push_up ( i ) ;
}
return ;
} int main ( ) {
int N , Q ;
freopen("weed.in", "r", stdin);
freopen("weed.out", "w", stdout);
scanf ( "%d%d" , &N , &Q ) ;
for ( int i= ; i<=N ; ++i ) scanf ("%d%d" , op + i , arr + i ) ;
Build_Tree ( , N , ) ;
while ( Q-- ) {
int tmp = INPUT ( ) ;
Update_Tree ( , tmp ) ;
printf ( "%d\n" , tr[ ].Cnt ) ;
}
fclose(stdin);
fclose(stdout);
Never Explode ;
}
Weed
NOIP_RP++;
2016-10-07 20:28:07
(完)
20161003 NOIP 模拟赛 T2 解题报告的更多相关文章
- 20161005 NOIP 模拟赛 T2 解题报告
beautiful 2.1 题目描述 一个长度为 n 的序列,对于每个位置 i 的数 ai 都有一个优美值,其定义是:找到序列中最 长的一段 [l, r],满足 l ≤ i ≤ r,且 [l, r] ...
- 20161023 NOIP 模拟赛 T2 解题报告
Task 2.回文串计数 (calc.pas/calc.c/calc.cpp) [题目描述] 虽然是一名理科生,Mcx常常声称自己是一名真正的文科生.不知为何,他对于背诵总有一种莫名的热爱,这也促使他 ...
- 【HHHOJ】NOIP模拟赛 玖 解题报告
点此进入比赛 得分: \(100+20+100=220\)(还不错) 排名: \(Rank\ 16\) \(Rating\):\(+20\) \(T1\):[HHHOJ263]「NOIP模拟赛 玖」三 ...
- 【HHHOJ】NOIP模拟赛 捌 解题报告
点此进入比赛 得分: \(30+30+70=130\)(弱爆了) 排名: \(Rank\ 22\) \(Rating\):\(-31\) \(T1\):[HHHOJ260]「NOIP模拟赛 捌」Dig ...
- NOIP欢乐模拟赛 T2 解题报告
小澳的坐标系 (coordinate.cpp/c/pas) [题目描述] 小澳者表也,数学者景也,表动则景随矣. 小澳不喜欢数学,可数学却待小澳如初恋,小澳睡觉的时候也不放过. 小澳的梦境中出现了一个 ...
- CH Round #55 - Streaming #6 (NOIP模拟赛day2)解题报告
T1九九归一 描述 萌蛋在练习模n意义下的乘法时发现,总有一些数,在自乘若干次以后,会变成1.例如n=7,那么5×5 mod 7=4,4×5 mod 7=6,6×5 mod 7=2,2×5 mod 7 ...
- CH Round #54 - Streaming #5 (NOIP模拟赛Day1)解题报告
最近参加了很多CH上的比赛呢~Rating--了..题目各种跪烂.各种膜拜大神OTZZZ T1珠 描述 萌蛋有n颗珠子,每一颗珠子都写有一个数字.萌蛋把它们用线串成了环.我们称一个数字串是有趣的,当且 ...
- 20161007 NOIP 模拟赛 T1 解题报告
排序 3.1 题意描述 众所周知,熟练掌握至少一种排序算法是参加NOIP的必备技能.常见的排序算法有冒泡 排序.归并排序.快速排序.奇偶排序.猴子排序.梳排序.鸡尾酒排序.臭皮匠排序等. 在这里,介绍 ...
- 20161005 NOIP 模拟赛 T3 解题报告
subset 3.1 题目描述 一开始你有一个空集,集合可以出现重复元素,然后有 Q 个操作 1. add s 在集合中加入数字 s. 2. del s 在集合中删除数字 s.保证 s 存在 3. c ...
随机推荐
- JavaScript - 引用类型
对象在JavaScript中被称为引用类型的值. 引用类型和传统面向对象设计中的类相似,但实现不同. Object是一个基础类型,其他所有类型都从Object继承了基本的行为. Array类型,Dat ...
- linux网络协议
网络协议 本章节主要介绍linxu网络模型.以及常用的网络协议分析以太网协议.IP协议.TCP协议.UDP协议 一.网络模型 TCP/IP分层模型的四个协议层分别完成以下的功能: 第一层 网络接口层 ...
- BZOJ 3289: Mato的文件管理 莫队+BIT
3289: Mato的文件管理 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的 ...
- I/O复用模型之epoll学习
简介: epoll是linux下多路复用I/O接口select/poll的增强版,它能够显著提高程序在大量并发连接中只有少量活跃的情况下的系统cpu利用率,原因是它会复用文件描述符集合来传递结果而不用 ...
- 小甲鱼PE详解之IMAGE_DOS_HEADER结构定义即各个属性的作用(PE详解01)
(注:最左边是文件头的偏移量.) IMAGE_DOS_HEADER STRUCT { +0h WORD e_magic // Magic DOS signature MZ(4Dh 5Ah) ...
- Input对象的type类型
Input表示Form表单中的一种输入对象,其又随Type类型的不同而分文本输入框,密码输入框,单选/复选框,提交/重置按钮等,下面一一介绍. 1,type=text 输入类型是text ...
- PowerDesigner 16.5
PowerDesigner165_破解文件.rar 链接:http://pan.baidu.com/s/1hqEDUCG 636KB PowerDesigner165_Evaluation ...
- 廖雪峰教程笔记:js中map和reduce的用法
举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个数组[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map实现如下: 由于map()方法定义在JavaScript的 ...
- PHP之echo/print
1.PHP中有两个基本的输出方式:echo和print: 2.echo和print的区别: **echo:可以输出一个或多个字符串: **print:只允许输出一个字符串,返回值总为1: 3.echo ...
- Swift3.0语言教程替换子字符串
Swift3.0语言教程替换子字符串 Swift3.0语言教程替换子字符串,替换子字符串其实就是将字符串中的子字符串删除,然后再进行添加.为了让这一繁琐的过程变的简单,NSString提供了替换子字符 ...