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;
}
posted @ 2018-11-05 14:00  水题收割者  阅读(172)  评论(0编辑  收藏  举报