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. 将GMap封装为Activex供QT使用(工具:VS2017,QT5.12) 更新部署到其它电脑

    由于一开始定的开发平台在QT下,到后面要加入地图控件.qt里本身带有地图qmap(在qt的官方案例中可以找到,用qml做的),但只有固定的几个地图源,要做google或者bing地图,时间和人力不允许 ...

  2. 线性表的顺序存储C++代码实现

      关于线性表的概念,等相关描述请参看<大话数据结构>第三章的内容, 1 概念   线性表list:零个或多个数据的有限序列.   可以这么理解:糖葫芦都吃过吧,它就相当于一个线性表,每个 ...

  3. c++ 队列的基本应用

    c++ 队列的基本应用 题目描述 现在去营业厅办理业务,都要先取号,再等待叫号.叫号系统有两种模式: 1.取号,取号时要输入自己的11位电话号码,号码按取号的顺序存在系统中: 2.叫号,叫号时会显示当 ...

  4. 微信开发:微信js_sdk分享,使用场景,网页在微信app内部分享时的标题与描述,包括logo设置(一)

    主要有下面几步.首先大家先分清楚 小程序的appid,appSecret 跟公众号的appid,appSecret是不一样的.因为这两个都能拿到token,且是不同的值. 准备开始: 1.准备好 公众 ...

  5. kuangbin专题 专题一 简单搜索 Oil Deposits HDU - 1241

    题目链接:https://vjudge.net/problem/HDU-1241 题意:问有几个油田,一个油田由相邻的‘@’,组成. 思路:bfs,dfs都可以,只需要遍历地图,遇到‘@’,跑一遍搜索 ...

  6. scala刷LeetCode--21 合并两个有序链表

    一.题目描述 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 二.示例 输入:1->2->4, 1->3->4输出:1->1 ...

  7. pycharm在服务器上远程调试 mac版本

    1. 首先要配置tools 2.点 +,选择SFTP, 填写 New server name:随便填写 3.然后填写 connection 和 Mapping Host:填写远程连接的ip地址 Use ...

  8. mysql中id值被重置的情况

    MySQL中,如果你为一张使用了innodb引擎的表指定了一auto_increment列,那么这张表会有一个auto_increment计数器,专门记录当前auto_increment的相关值,用来 ...

  9. 20141102-微信.NET-笔记

    http://weixin.senparc.com/ 欢迎使用 微信公众平台SDK!     Senparc.Weixin.MP.dll 使用 Senparc.Weixin.MP.dll 整合网站与微 ...

  10. Java核心技术中的程序片段

    import java.io.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import ...