https://codeforces.com/contest/1690/problem/G
#797 Div.3 G. Count the Trains 思维_Strezia的博客-CSDN博客
(上图是一开始的错误思路;
当时是这么想的,修改某个点的贡献是看前一个是否小于,小于贡献+1,然后二分到后面第一个小于他的位置,删去这个区间的贡献,然后修改这个区间的值;。。其他都好说,但这个修改这个区间的值,实在不知道咋处理;
结果正解压根就不需要修改这个区间的值——【为什么能想到:让我们想一个极端情况,每次都是修改头尾,实际上中间的压根对答案不产生贡献——也就是说我只要修改产生贡献的点就行了——什么样的点产生贡献呢,维护一个严格下降序列就行】
总之还是很值得再做的一道题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+15;
const int mo = 988244353;
#define pb push_back
#define pii pair<int,int>
#define ft first
#define sd second
#define debug1(x) cerr<<"! "<<x<<endl;
#define debug2(x,y) cerr<<"# "<<x<<" "<<y<<endl;
map<int,int>mp;
void add(int i,int x){
mp[i]=x;
auto it=mp.find(i);
if(it!=mp.begin() && x>=prev(it)->sd){
mp.erase(it);
return;
}
while(next(it)!=mp.end() && x<=next(it)->sd)
mp.erase(next(it));
}
void slv(){
int n,m;cin>>n>>m;mp.clear();
vector<int>a(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];
add(i,a[i]);
}
while(m--){
int i,x;cin>>i>>x;
a[i]-=x;
add(i,a[i]);
cout<<mp.size()<<" \n"[!m];
}
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
int t;cin>>t;
while(t--){
slv();
}
}