標籤:else 長度 rev 維護 input current 情況 contain const
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
Problem DescriptionThere 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?
InputThe 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.
OutputFor each query, display the answer in a single line.
給你長度為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|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\n",cnt[1]); //還原 update(1,1,n,pos,v[pos]); } } return 0;}
hdu 6406 Taotao Picks Apples 線段樹 單點更新