为了方便取前缀 min,我将 min 数组 b0 赋为 109。
然后 #4 正好卡掉了这个东西,我的代码是这样的:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int T,n,m,a[N],b[N],ans;
struct node{int l,r,tag,sum;}t1[N<<2],t2[N<<2];
//1存前缀min,2存分节位置
//1:区间覆盖,单点查询
//2:区间覆盖,区间求和
void up(int u){
t2[u].sum=t2[u<<1].sum+t2[u<<1|1].sum;
}
void down1(int u){
if(t1[u].tag<0)return;
t1[u<<1].tag=t1[u].tag;
t1[u<<1|1].tag=t1[u].tag;
t1[u].tag=-1;
}
void down2(int u){
if(t2[u].tag<0)return;
t2[u<<1].tag=t2[u].tag;
t2[u<<1|1].tag=t2[u].tag;
t2[u<<1].sum=(t2[u<<1].r-t2[u<<1].l+1)*t2[u].tag;
t2[u<<1|1].sum=(t2[u<<1|1].r-t2[u<<1|1].l+1)*t2[u].tag;
t2[u].tag=-1;
}
void build1(int u,int L,int R){
t1[u].l=L;t1[u].r=R;t1[u].tag=-1;
if(L==R)return;
int mid=L+R>>1;
build1(u<<1,L,mid);build1(u<<1|1,mid+1,R);
}
void build2(int u,int L,int R){
t2[u].l=L;t2[u].r=R;t2[u].tag=-1;t2[u].sum=0;
if(L==R)return;
int mid=L+R>>1;
build2(u<<1,L,mid);build2(u<<1|1,mid+1,R);
}
int query1(int u,int pos){
if(t1[u].l==t1[u].r)return t1[u].tag;
int mid=t1[u].l+t1[u].r>>1;
down1(u);
if(mid>=pos)return query1(u<<1,pos);
else return query1(u<<1|1,pos);
}
int query2(int u,int L,int R){
if(t2[u].l>R||t2[u].r<L)return 0;
if(t2[u].l>=L&&t2[u].r<=R)return t2[u].sum;
down2(u);
return query2(u<<1,L,R)+query2(u<<1|1,L,R);
}
void modify1(int u,int L,int R,int val){
if(t1[u].r<L||t1[u].l>R)return;
if(t1[u].l>=L&&t1[u].r<=R)return t1[u].tag=val,void();
down1(u);
modify1(u<<1,L,R,val);modify1(u<<1|1,L,R,val);
}
void modify2(int u,int L,int R,int val){
if(t2[u].r<L||t2[u].l>R)return;
if(t2[u].l>=L&&t2[u].r<=R)return t2[u].tag=val,t2[u].sum=(t2[u].r-t2[u].l+1)*val,void();
down2(u);
modify2(u<<1,L,R,val);modify2(u<<1|1,L,R,val);
up(u);
}
void solve(){
scanf("%d%d",&n,&m);ans=0;
for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=min(b[i-1],a[i]);
build1(1,1,n);build2(1,1,n);
for(int i=1;i<=n;i++)if(b[i]!=b[i-1])ans++,modify2(1,i,i,1);
for(int i=1;i<=n;i++)modify1(1,i,i,b[i]);
// for(int i=1;i<=n;i++)printf("%d ",query1(1,i));puts("");
// for(int i=1;i<=n;i++)printf("%d ",query2(1,i,i));puts("");
while(m--){
int x,y;
scanf("%d%d",&x,&y);a[x]-=y;
if(query1(1,x)<=a[x]){printf("%d ",ans);continue;}
int L=x+1,R=n,pos=x;
while(L<=R){
int mid=L+R>>1;
if(query1(1,mid)<a[x])R=mid-1;
else L=mid+1,pos=max(pos,mid);
}
if(x+1<=pos)modify2(1,x+1,pos,0);
modify2(1,x,x,1);
modify1(1,x,pos,a[x]);
printf("%d ",ans=query2(1,1,n));
// for(int i=1;i<=n;i++)printf("%d ",query1(1,i));puts("");
// for(int i=1;i<=n;i++)printf("%d ",query2(1,i,i));puts("");
}
return puts(""),void();
}
signed main(){
// freopen("temp.in","r",stdin);
// freopen("CF1690G.out","w",stdout);
b[0]=1e9;
scanf("%d",&T);
while(T--)solve();
return 0;
}
#4 的 a1 在某个时刻变成了 109,导致答案少了 1。
这个问题害得我调了将近 1h,希望这个帖子能帮到你。