临文乍了了,彻卷兀若无。这篇文章主要讲述hdu 6406 Taotao Picks Apples 线段树 单点更新相关的知识,希望能为你提供帮助。
Taotao Picks ApplesTime Limit: 2000/2000 MS (java/Others)
Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2506
Accepted Submission(s): 786
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.
给你长度为n的序列, 然后从位置1,寻找单调栈的最大长度
然后修改 v[pos] = val, 再求 单调栈的最大长度
但是队友说是单调栈 ,我就用线段树维护了个单调栈,但是我维护的好像有些SB,就是每次左区间的最大值+(用单调栈跑一次最大长度)
然后完美的T了 ,然后就没管这道题了
后来看了一个人的题解,是这样子分析的
对于每一个区间, 贡献只能从左区间
+ 右区间的部分选择
然后 考虑: 两种情况 ,如果 右区间的最大值 <
= 左区间最大值,那么右区间肯定没有贡献,为0
【hdu 6406 Taotao Picks Apples 线段树 单点更新】然后考虑 :如果右区间的最大值 >
左区间最大值,那么问题可以递归
右区间的左儿子 和 右儿子的情况
这样的复杂度 大概是T*m*logn*logn (单点更新val值一个log
然后每次 合并区间的时候又要一个log)
#include < bits/stdc++.h> using namespace std; const int N = 1e5+10; #define ls rt< < 1 #define rs rt< < 1|1int mx[N< < 2],cnt[N< < 2]; int query(int rt,int l,int r,int v) { if(l==r) return mx[rt] > v; if(mx[rt] < = v) return 0; int m = (l+r)> > 1; if(mx[ls] < = v) return query(rs,m+1,r,v); else return cnt[rt]-cnt[ls]+query(ls,l,m,v); } int n,m,v[N]; void build(int rt,int l,int r) { mx[rt] = cnt[rt] =0; if(l == r) { mx[rt]=v[l]; cnt[rt]=1; return ; } int m=(l+r)> > 1; build(ls,l,m); build(rs,m+1,r); mx[rt]=max(mx[ls], mx[rs]); cnt[rt] = cnt[ls] + query(rs,m+1,r,mx[ls]); }void update(int rt,int l,int r,int pos,int val) { if(l==r & & l == pos) { mx[rt]=val; cnt[rt] = 1; return ; } int m = (l+r)> > 1; if(pos < = m) update(ls,l,m,pos,val); else update(rs,m+1,r,pos,val); mx[rt]=max(mx[ls], mx[rs]); cnt[rt] = cnt[ls] + query(rs,m+1,r,mx[ls]); }int main() { //freopen("in.txt","r",stdin); int T; scanf("%d",& T); while (T--) { scanf("%d %d", & n, & m); for(int i=1; i< =n; i++) scanf("%d",& v[i]); build(1,1,n); while (m--) { int pos, val; scanf("%d %d",& pos,& val); //pos位置 更新成val update(1,1,n,pos,val); printf("%d ",cnt[1]); //还原 update(1,1,n,pos,v[pos]); } } return 0; }
推荐阅读
- Android手机多媒体——拍照和相册
- Excel Application操作指南
- Excel.Application使用手册
- 读spring源码-ClassPathXmlApplicationContext-getBean
- Excel.Application class
- android摄像头(camera)之 v4l2的c测试代码
- Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported for @RequestBod
- Android手机多媒体——通知
- java基础增强(统计网上app下载情况,并排序)