题意:
有nnn节火车车厢,从左到右依次是头至尾,每个车厢有一个最高速度viv_{i}vi,如果后面的车的速度不小于前车vi+1≥viv_{i+1}\geq v_{i}vi+1≥vi,那么后车的速度会受到限制,会变为前车速度viv_{i}vi,反之则不受影响。我们把连续的极长一段的共速车厢看作一辆完整火车。给出mmm个操作,每个操作给出两个整数x dxx\ dxx dx,代表xxx车厢的最高速度减少dxdxdx,在每次操作后给出能组成的火车数。
方法:
利用mapmapmap或vectorvectorvector,每次只保存火车头,在操作的时候,我们检查一下xxx是否在mapmapmap里,如果在mapmapmap里有xxx,那么这节火车头降速,然后检查后面的火车头速度是否不小于这个新的vxv_{x}vx,如果后面的火车头的速度≥vx\geq v_{x}≥vx,那么这个火车头会被xxx同化,直接并入xxx所在的火车,删去这个火车头即可;如果mapmapmap里没有xxx,那么我们需要检查一下他是否脱离了前面火车头的控制,如果脱离了控制,就说明组成了一节新的火车,然后再检查后面的是否速度是否≥\geq≥这个新的火车头的速度,如果是,那么被这个新的同化,把后面的删去即可。每次操作后输出map.size()map.size()map.size()即可
#include<bits/stdc++.h>
#define ll long long
#define fr first
#define se second
using namespace std;
int read()
{
int ret=0,base=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') base=-1;
ch=getchar();
}
while(isdigit(ch))
{
ret=(ret<<3)+(ret<<1)+ch-48;
ch=getchar();
}
return ret*base;
}
int n,m,a[100005];
vector<int>ans;
map<int,int>map1;
void work()
{
map1.clear();
ans.clear();
n=read();m=read();
for(int i=1;i<=n;i++) a[i]=read();
int l=1,r=1;
while(l<=n)
{
while(r+1<=n&&a[r+1]>=a[l]) r++;
map1[l]=a[l];
l=++r;
}
while(m--)
{
int x=read(),dx=read();
a[x]-=dx;
if(map1.count(x))
{
map1[x]-=dx;
auto it=map1.lower_bound(x); it++;
while(it!=map1.end()&&it->se>=map1[x]){
map1.erase(it--);it++;
}
}
else
{
auto it=map1.lower_bound(x); it--;
//it不可能是begin(),因为第一节车厢一定是一个火车头
if(it->se>a[x])
{
map1[x]=a[x];
it=map1.lower_bound(x); it++;
while(it!=map1.end()&&it->se>=map1[x]){
map1.erase(it--);it++;
}
}
}
ans.push_back(map1.size());
}
for(auto i:ans) printf("%d ",i);
putchar('\n');
}
int main()
{
int t=read();
while(t--) work();
return 0;
}