Luogu P3616 富金森林公園

2022-01-10 20:41:36 字數 1995 閱讀 1445

我們首先考慮一塊石頭高度變化對每個高度的查詢的答案的影響,

我們要記錄,對於每個高度的查詢的答案

所以要離散化高度(不然哪開的下陣列啊)

不難發現,一次變化的對於不同高度的影響,對於一段連續高度是相同的

即一次修改操作,對於一段連續高度的答案,影響相同,滿足區間修改性質

就決定是你了,樹狀陣列

具體來說,考慮修改位置修改前後和兩邊的高度關係

但是情況很多,不妨把修改操作換成先刪除(把高度降為0),再插入

考慮刪除,插入的話,反過來就好,中間的是刪除位置

情況1:中間比兩邊低

最簡單的情況,不難發現,刪除掉中間的只能讓高度為$part1$的區間的答案$+1$,因為它割裂了兩邊的連續區間

情況2:中間比兩邊高

最高的區間影響就很廣了

對於$part1:$它的刪除會割裂兩邊的區間$val~of~part1++$

對於$part2:$因為兩邊沒有構成連續區間,所以沒有影響

對於$part3:$原來是有露出來的,現在沒了,當然要減掉了

情況3:中間的高度也中等

也很簡單了,只對$part1$有影響

然而這樣處理的只是答案的變化,我們還需要統計初始答案

還是考慮高度變化對答案的影響,不難發現,隨著高度上公升,未被覆蓋的點的個數是單調不公升的

按高度開$vector$,把每個高度恰好被覆蓋的所有位置扔進去

從小到大列舉高度,先將這個高度的答案設為上乙個高度的答案,取出這個高度恰好被覆蓋的所有位置,統計這個位置的影響

如果它比兩邊高,模擬上面情況2,答案減一

低呢,答案加一

這樣我們就解決了這個問題

上**:

#include#include

#include

#include

using

namespace

std;

const

int maxn=2e5+10

;vector

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)int sum(int

x)

return

ret;

}void add(int x,int

ch)}

intmain()

for(int i=1;i<=m;i++)

sort(mp+1,mp+cnt+1

); cnt=unique(mp+1,mp+cnt+1)-mp-1

;

for(int i=1;i<=n;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++)

}for(int i=1;i<=m;i++)

}return0;

}

洛谷P3616 富金森林公園

博艾的富金森林公園裡有乙個長長的富金山脈,山脈是由一塊塊巨石並列構成的,編號從1到n。每乙個巨石有乙個海拔高度。而這個山脈又在乙個盆地中,盆地裡可能會積水,積水也有乙個海拔高度,所有嚴格低於這個海拔高度的巨石,就會在水面下隱藏。由於地殼運動,巨石的海拔高度可能會隨時變化,每次一塊的巨石會變成新的海拔...

洛谷 P3616 富金森林公園

題鏈 題解 樹狀陣列,本題思路挺巧妙。考慮這種暴力演算法 設h i 為i位置的高度,水面的高度為b 從左列舉到右,如果 h i 1 基於上述暴力,可以得出 如果 h i 1 h i 且詢問的 b 在這兩個h值之間,則會貢獻答案。所以,用資料結構維護區間修改 把區間h i 1 1 h i 的值加一 和...

樹狀陣列 洛谷 P3616 富金森林公園

達成成就 noip題想不出!我是怎麼做到想去寫cdq分治加並查集的 還寫不出來 資料結構學傻系列 其實是noip題 這樣的話高度一樣怎麼辦 我們把乙個高度放大成乙個高度區間就可以避免有相同數字了 include include include using namespace std inline c...