Problem Description

There is an apple tree in front of Taotao's house. When autumn comes, n apples on the tree ripen, and Taotao will go to pick these apples.

When Taotao picks apples, Taotao scans these apples from the first one to the last one. If the current apple is the first apple, or it is strictly higher than the previously picked one, then Taotao will pick this apple; otherwise, he will not pick.

Given the heights of these apples h1,h2,⋯,hn, you are required to answer some independent queries. Each query is two integers p,q, which asks the number of apples Taotao would pick, if the height of the p-th apple were q (instead of hp). Can you answer all these queries?

 

Input

The first line of input is a single line of integer T (1≤T≤10), the number of test cases.

Each test case begins with a line of two integers n,m (1≤n,m≤105), denoting the number of apples and the number of queries. It is then followed by a single line of n integers h1,h2,⋯,hn (1≤hi≤109), denoting the heights of the apples. The next m lines give the queries. Each of these m lines contains two integers p (1≤p≤n) and q (1≤q≤109), as described in the problem statement.

 

Output

For each query, display the answer in a single line.
 

Sample Input

1
5 3
1 2 3 4 4
1 5
5 5
2 3
 

Sample Output

1
5
3

Hint

For the first query, the heights of the apples were 5, 2, 3, 4, 4, so Taotao would only pick the first apple.

For the second query, the heights of the apples were 1, 2, 3, 4, 5, so Taotao would pick all these five apples.

For the third query, the heights of the apples were 1, 3, 3, 4, 4, so Taotao would pick the first, the second and the fourth apples.

 
 

Solution

拿到题最开始想用前缀和维护答案,但是没有理清思路,后来就乱了。看到一篇大神的线段树直接维护答案的题解,简单理了一下思路

对于线段树,维护区间最大值以及区间从左往右上升长度(即答案),我们注意到一个区间的答案=左区间答案数+右区间在左区间最大值基础上的贡献

对于一个查询query(rt,v)表示将区间t之前的一个数改为v后的区间rt的对答案的贡献,

rt->maxx<v直接返回0,总的区间最大值小于v,这个区间不可能贡献答案

否则若rt->lson->maxx>v 此时只需关注左区间,因为右区间此时的贡献值和v不相关,注意这时的返回答案应该是tr[rt].cnt-tr[lson].cnt+query(lson,v),而不是tr[rson].cnt+query(lson,v)

这两者是不等价的,因为一个cnt表示的是当前区间从左到右的上升长度,而tr[rson].cnt仅仅关注的是右区间,没有和整体直接挂钩

再如果tr->lson->maxx<=v,此时左区间对答案无贡献,但右区间存在,查询右区间

大概就是这样,线段树维护答案很灵活感觉,唉本人垃圾是想不到了

贴一段大概理解之后写的ac代码吧


 #include <bits/stdc++.h>
#define lson rt << 1
#define rson rt << 1 | 1
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pa = pair<int, int>;
using ld = long double;
int n, m, k;
const int maxn = 1e5 + ;
const int mod = ;
int pre[maxn];
template <class T>
inline T read(T &ret)
{
int f = ;
ret = ;
char ch = getchar();
while (!isdigit(ch))
{
if (ch == '-')
f = -;
ch = getchar();
}
while (isdigit(ch))
{
ret = (ret << ) + (ret << ) + ch - '';
ch = getchar();
}
ret *= f;
return ret;
}
template <class T>
inline void write(T n)
{
if (n < )
{
putchar('-');
n = -n;
}
if (n >= )
{
write(n / );
}
putchar(n % + '');
}
int a[maxn];
struct node
{
int l, r, cnt, maxx;
} tr[maxn << ];
int query(int rt, int v)
{
int l = tr[rt].l;
int r = tr[rt].r;
if (l == r)
return tr[rt].maxx > v;
if (tr[rt].maxx < v)
return ;
int mid = l + r >> ;
if (tr[lson].maxx > v) //疑惑,为什么写出tr[rson].cnt+query(lson,v)答案不对
//啊左右区间和大区间并不相等,大区间=左区间+右区间贡献
return tr[rt].cnt - tr[lson].cnt + query(lson, v);
else
return query(rson, v);
}
void pushup(int rt)
{
tr[rt].maxx = max(tr[lson].maxx, tr[rson].maxx);
tr[rt].cnt = tr[lson].cnt + query(rson, tr[lson].maxx);
}
void build(int rt, int l, int r)
{
tr[rt].l = l;
tr[rt].r = r;
if (l == r)
{
tr[rt].cnt = ;
tr[rt].maxx = a[l];
return;
}
int mid = l + r >> ;
build(lson, l, mid);
build(rson, mid + , r);
pushup(rt);
}
void update(int rt, int L, int v)
{
int l = tr[rt].l;
int r = tr[rt].r;
if (l == r && l == L)
{
tr[rt].maxx = v;
return;
}
int mid = l + r >> ;
if (L <= mid)
update(lson, L, v);
else
update(rson, L, v);
pushup(rt);
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
int t;
cin >> t;
while (t--)
{
cin >> n >> m;
for (int i = ; i <= n; i++)
cin >> a[i];
build(, , n);
while (m--)
{
int p, q;
cin >> p >> q;
update(, p, q);
cout << tr[].cnt << "\n";
update(, p, a[p]);
}
}
return ;
}

hdu 6406 Taotao Picks Apples (线段树)的更多相关文章

  1. hdu 6406 Taotao Picks Apples 线段树 单点更新

    Taotao Picks Apples Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Ot ...

  2. HDU 6406 Taotao Picks Apples 线段树维护

    题意:给个T,T组数据: 每组给个n,m:n个数,m个操作: (对序列的操作是,一开始假设你手上东西是-INF,到i=1时拿起1,之后遍历,遇到比手头上的数量大的数时替换(拿到手的算拿走),问最后拿走 ...

  3. [乱搞]hdu 6406 Taotao picks apples 笛卡尔树+倍增

    题目链接 Problem Description There is an apple tree in front of Taotao's house. When autumn comes, n app ...

  4. HDU 6406 Taotao Picks Apples & FJUT3592 做完其他题后才能做的题(线段树)题解

    题意(FJUT翻译HDU): 钱陶陶家门前有一棵苹果树. 秋天来了,树上的n个苹果成熟了,淘淘会去采摘这些苹果. 到园子里摘苹果时,淘淘将这些苹果从第一个苹果扫到最后一个. 如果当前的苹果是第一个苹果 ...

  5. hdu 6406 Taotao Picks Apples (2018 Multi-University Training Contest 8 1010)(二分,前缀和)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6406 思路: 暴力,预处理三个前缀和:[1,n]桃子会被摘掉,1到当前点的最大值,1到当前点被摘掉的桃子的 ...

  6. HDU - 6406 Taotao Picks Apples (RMQ+dp+二分)

    题意:N个高度为hi的果子,摘果子的个数是从位置1开始从左到右的严格递增子序列的个数.有M次操作,每次操作对初始序列修改位置p的果子高度为q.每次操作后输出修改后能摘到得数目. 分析:将序列分为左.右 ...

  7. hdu6406 Taotao Picks Apples(线段树)

    Taotao Picks Apples 题目传送门 解题思路 建立一颗线段树,维护当前区间内的最大值maxx和可摘取的苹果数num.最大值很容易维护,主要是可摘取的苹果数怎么合并.合并左右孩子时,左孩 ...

  8. 【杂题总汇】HDU-6406 Taotao Picks Apples

    [HDU 6406]Taotao Picks Apples 多校赛的时候多写了一行代码就WA了……找了正解对拍,在比赛结束后17分钟AC了

  9. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

随机推荐

  1. 小白也能看懂的 Laravel 核心概念讲解

    自动依赖注入 什么是依赖注入,用大白话将通过类型提示的方式向函数传递参数. 实例 1 首先,定义一个类: /routes/web.php class Bar {} 假如我们在其他地方要使用到 Bar  ...

  2. Java多线程学习(吐血超详细总结)

    Java多线程学习(吐血超详细总结) 林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实 ...

  3. Codeblocks 批量注释与对齐快捷键的教学方法

    Ctrl+Shift+C 批量注释 Ctrl+shift+X 批量取消注释 Click Settings->Editor->KeyboardShortcuts (in the left o ...

  4. 基于STM32之UART串口通信协议(一)详解

    一.前言 1.简介 写的这篇博客,是为了简单讲解一下UART通信协议,以及UART能够实现的一些功能,还有有关使用STM32CubeMX来配置芯片的一些操作,在后面我会以我使用的STM32F429开发 ...

  5. 6tunnel数据转发

    6tunnel 一条命令实现端口映射.数据转发,实现代理服务器功能. 安装脚本 #!/bin/bash DIR=/opt/software INSTALL=6tunnel-master.tar.gz ...

  6. InstallShield 2018 打包安装

    关于InstallShield 2018打包安装程序的使用 1. 下载InstallShield2018 建议使用新的版本,毕竟新的版本功能功能全.问题少.用户体验佳. 下载地址:http://www ...

  7. 在FPS游戏中,玩家对音画同步感知的量化与评估

    前言 在游戏测试中,音画同步测试是个难点(所谓游戏音画同步:游戏中,音效与画面的同步程度),现在一般采用人工主观判断的方式测试,但这会带来2个问题: 无法准确量化,针对同一场景的多次测试结果可能会相反 ...

  8. CDQZ集训DAY3 日记

    早上起来之后依然开始考试.然而由于校方觉得都挨在一起没有考试氛围,分了两个机房,一开始还没人去,听说另一个机房配置好了之后一堆人开始往外冲,由于我天真的数了一下我是不是要走的,晚了一步,于是乎被教练员 ...

  9. C语言指针专题——使用指针要注意这些

    本文为原创,欢迎转发: 欢迎关注微博与微信号:C语言编程技术分享 C语言中,指针的概念有点难懂,使用起来稍微不注意,也会遇到各种问题.在本文中,我列举出了几个使用指针不当的方式,希望朋友们在编程实践中 ...

  10. Oracle使用MyBatis中RowBounds实现分页查询

    Oracle中分页查询因为存在伪列rownum,sql语句写起来较为复杂,现在介绍一种通过使用MyBatis中的RowBounds进行分页查询,非常方便. 使用MyBatis中的RowBounds进行 ...