咱們首先考慮一塊石頭高度變化對每一個高度的查詢的答案的影響,
即咱們要記錄,對於每一個高度的查詢的答案
因此要離散化高度(否則哪開的下數組啊)
不難發現,一次變化的對於不一樣高度的影響,對於一段連續高度是相同的
即一次修改操做,對於一段連續高度的答案,影響相同,知足區間修改性質
就決定是你了,樹狀數組
具體來講,考慮修改位置修改先後和兩邊的高度關係
可是狀況不少,不妨把修改操做換成先刪除(把高度降爲0),再插入
考慮刪除,插入的話,反過來就好,中間的是刪除位置
狀況1:中間比兩邊低
最簡單的狀況,不難發現,刪除掉中間的只能讓高度爲$part1$的區間的答案$+1$,由於它割裂了兩邊的連續區間
狀況2:中間比兩邊高
最高的區間影響就很廣了
對於$part1:$它的刪除會割裂兩邊的區間$val~of~part1++$
對於$part2:$由於兩邊沒有構成連續區間,因此沒有影響
對於$part3:$原來是有露出來的,如今沒了,固然要減掉了
狀況3:中間的高度也中等
也很簡單了,只對$part1$有影響
然而這樣處理的只是答案的變化,咱們還須要統計初始答案
仍是考慮高度變化對答案的影響,不難發現,隨着高度上升,未被覆蓋的點的個數是單調不升的
按高度開$vector$,把每一個高度剛好被覆蓋的全部位置扔進去
從小到大枚舉高度,先將這個高度的答案設爲上一個高度的答案,取出這個高度剛好被覆蓋的全部位置,統計這個位置的影響
若是它比兩邊高,類比上面狀況2,答案減一
低呢,答案加一
這樣咱們就解決了這個問題
上代碼:
ios
#include<iostream> #include<cstdio> #include<algorithm> #include<vector>
using namespace std; const int maxn=2e5+10; vector<int>v[2*maxn]; int pre[2*maxn],n,m,a[maxn],mp[2*maxn],op[maxn],cnt,b[maxn],d[maxn],c[2*maxn]; bool vis[2*maxn]; int lowbit(int x) { return x&-x; } int sum(int x) { int ret=0; while(x) { ret+=c[x]; x-=lowbit(x); } return ret; } void add(int x,int ch) { while(x<=cnt) { c[x]+=ch; x+=lowbit(x); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); mp[++cnt]=a[i]; } for(int i=1;i<=m;i++) { scanf("%d",&op[i]); if(op[i]==1) scanf("%d",&b[i]),mp[++cnt]=b[i]; else scanf("%d%d",&d[i],&b[i]),mp[++cnt]=b[i]; } sort(mp+1,mp+cnt+1); cnt=unique(mp+1,mp+cnt+1)-mp-1; for(int i=1;i<=n;i++) { a[i]=lower_bound(mp+1,mp+cnt+1,a[i])-mp; v[a[i]+1].push_back(i); } for(int i=1;i<=m;i++) b[i]=lower_bound(mp+1,mp+cnt+1,b[i])-mp; pre[1]=1,vis[0]=vis[n+1]=1; for(int i=2;i<=cnt;i++) { pre[i]=pre[i-1]; for(int j=0;j<v[i].size();j++) { int u=v[i][j]; vis[u]=1; if(!vis[u-1]&&!vis[u+1]) pre[i]++; else if(vis[u-1]&&vis[u+1]) pre[i]--; } } for(int i=1;i<=m;i++) { if(op[i]==1) printf("%d\n",pre[b[i]]+sum(b[i])); else { int tmp[5]; tmp[1]=a[d[i]-1],tmp[2]=a[d[i]],tmp[3]=a[d[i]+1]; sort(tmp+1,tmp+4); if(a[d[i]]>=a[d[i]-1]&&a[d[i]]>=a[d[i]+1]) add(tmp[2]+1,-1),add(tmp[3]+1,1); add(1,1),add(tmp[1]+1,-1); tmp[1]=a[d[i]-1],tmp[2]=b[i],tmp[3]=a[d[i]+1]; sort(tmp+1,tmp+4); if(b[i]>=a[d[i]-1]&&b[i]>=a[d[i]+1]) add(tmp[2]+1,1),add(tmp[3]+1,-1); add(1,-1),add(tmp[1]+1,1); a[d[i]]=b[i]; } } return 0; }