hdu 6406 Taotao Picks Apples 线段树 单点更新
Posted Draymonder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 6406 Taotao Picks Apples 线段树 单点更新相关的知识,希望对你有一定的参考价值。
Taotao Picks Apples
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2506 Accepted Submission(s): 786
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?
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.
给你长度为n的序列, 然后从位置1,寻找单调栈的最大长度
然后修改 v[pos] = val, 再求 单调栈的最大长度
但是队友说是单调栈 ,我就用线段树维护了个单调栈,但是我维护的好像有些SB,就是每次左区间的最大值+(用单调栈跑一次最大长度)
然后完美的T了 ,然后就没管这道题了
后来看了一个人的题解,是这样子分析的
对于每一个区间, 贡献只能从左区间 + 右区间的部分选择
然后 考虑: 两种情况 ,如果 右区间的最大值 <= 左区间最大值,那么右区间肯定没有贡献,为0
然后考虑 :如果右区间的最大值 > 左区间最大值,那么问题可以递归 右区间的左儿子 和 右儿子的情况
这样的复杂度 大概是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|1 int 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; }
以上是关于hdu 6406 Taotao Picks Apples 线段树 单点更新的主要内容,如果未能解决你的问题,请参考以下文章
hdu 6406 Taotao Picks Apples 锛?018 Multi-University Training Contest 8 1010锛夛紙浜屽垎锛屽墠缂€鍜岋級