分析:
mmp…lwc讲错题意了害我乱码了半个小时。。。
题意搞清楚了其实这题真心容易。
把每个询问离线了,按照位置从前往后排序,先处理出每个询问的位置及以前能拿的数量,以及当时的最高高度。
然后从前往后加入点,如果当前的高度高于之前的最高高度,则更新最高高度,并且长度++
处理询问时,如果这个询问更改后的值高于之前的最高高度,则直接把最高高度改为更改后的值,然后拿的数量+1
如果询问更改后的值不高于之前的最高高度,则把最高高度设为之前的最高高度,然后拿的数量不变。
然后再从后往前,维护一个高度递减的单调栈,对每个询问,再单调栈中二分找到比它大的最小的值,然后询问的答案加上那个位置向后能拿的数量即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
typedef long long ll;
typedef map<int,int>::iterator mit;
int n,t,q;
struct node{int pos,val,id;bool operator < (const node &a) const {if(pos==a.pos)return val<a.val;return pos<a.pos;}
}que[MAXN];
int a[MAXN],dp[MAXN];
int st[MAXN];
int ans[MAXN];
int main(){SF("%d",&t);while(t--){SF("%d%d",&n,&q);for(int i=1;i<=n;i++) SF("%d",&a[i]);int pos,val;for(int i=1;i<=q;i++){SF("%d%d",&pos,&val);que[i].pos=pos;que[i].val=val;que[i].id=i;}sort(que+1,que+1+q);int las=0,sum=0,top=0;for(int i=1;i<=q;i++){while(las<que[i].pos){if(a[las]>top){top=a[las];sum++;}las++;}if(que[i].val>top){ans[que[i].id]=sum+1;}else{ans[que[i].id]=sum;que[i].val=top;}//PF("{%d %d %d %d}\n",i,que[i].val,que[i].id,ans[que[i].id]);}las=n;top=0;for(int i=q;i>=1;i--){while(las>que[i].pos){while(top!=0&&a[st[top]]<=a[las])top--;if(top==0)dp[las]=1;elsedp[las]=dp[st[top]]+1;st[++top]=las;las--;}int l=1,r=top,res1=0;while(l<=r){int mid=(l+r)>>1;if(a[st[mid]]>que[i].val){res1=st[mid];l=mid+1;}elser=mid-1;}ans[que[i].id]+=dp[res1];}for(int i=1;i<=q;i++)PF("%d\n",ans[i]);}
}