ZROI #88
分析
我们考虑把每个A[i]考虑为山峰的高度,每次的B考虑为海平面
于是我们知道对于A[i]和A[i-1],如果A[i-1]<A[i]则在A[i-1]<B<=A[i]时会使陆地总数加一
于是树状数组维护即可
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define N cnt
int D[401000],a[200100],opt[200100],b[200100],c[200100],d[200100];
int id[400100],cnt;
int lb(int x){return x&(-x);}
void add(int x,int k){while(x<=N)D[x]+=k,x+=lb(x);}
void update(int le,int ri,int k){add(le,k),add(ri+1,-k);}
int q(int x){int res=0;while(x){res+=D[x];x-=lb(x);}return res;}
int wh(int x){return lower_bound(id+1,id+cnt+1,x)-id;}
int main(){
int n,m,i,j,k;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%d",&a[i]),id[++cnt]=a[i];
for(i=1;i<=m;i++){
scanf("%d",&opt[i]);
if(opt[i]==1)scanf("%d",&b[i]),id[++cnt]=b[i];
else scanf("%d%d",&c[i],&d[i]),id[++cnt]=d[i];
}
sort(id+1,id+cnt+1);
cnt=unique(id+1,id+cnt+1)-id-1;
for(i=1;i<=n;i++)
if(a[i]>a[i-1])
update(wh(a[i-1])+1,wh(a[i]),1);
for(i=1;i<=m;i++){
if(opt[i]==1)printf("%d\n",q(wh(b[i])));
else {
if(a[c[i]]<a[c[i]+1])update(wh(a[c[i]])+1,wh(a[c[i]+1]),-1);
if(a[c[i]-1]<a[c[i]])update(wh(a[c[i]-1])+1,wh(a[c[i]]),-1);
a[c[i]]=d[i];
if(a[c[i]]<a[c[i]+1])update(wh(a[c[i]])+1,wh(a[c[i]+1]),1);
if(a[c[i]-1]<a[c[i]])update(wh(a[c[i]-1])+1,wh(a[c[i]]),1);
}
}
return 0;
}