題目描述
博艾的富金森林公園裡有乙個長長的富金山脈,山脈是由一塊塊巨石並列構成的,編號從1到n。每乙個巨石有乙個海拔高度。而這個山脈又在乙個盆地中,盆地裡可能會積水,積水也有乙個海拔高度,所有嚴格低於這個海拔高度的巨石,就會在水面下隱藏。
由於地殼運動,巨石的海拔高度可能會隨時變化,每次一塊的巨石會變成新的海拔高度。當然,水面的高度也會隨時發生變化。
因為有這樣奇妙的地質奇觀,吸引了很多遊客來遊玩。uim作為乙個遊客,可以告訴你此時水位海拔,你得告訴他,能看到有幾個連續露出水面的部分。(與水面持平我們也認為是露出)
輸入輸出格式
輸入格式:
第一行兩個整數n和m,分別表示n塊石頭,m個詢問。
接下來一行,n個整數ai表示每個巨石的初始海拔。
接下來m行,每行有兩個或者三個數,每一行如果第乙個數是1,那麼後面跟乙個bj,表示水面海拔。如果第乙個數是2,後面跟兩個整數,cj和dj,表示編號cj的巨石海拔變為dj。
輸出格式:
對於每個"1"詢問,給出乙個整數答案,也就是露出了幾部分的山峰。
輸入輸出樣例
輸入樣例#1:
5 48 6 3 5 4
1 52 4 1
1 51 3
輸出樣例#1:21
2說明
10%的資料, n,m<=2000
另外30%的資料, 只有"1"的詢問。
100%的資料, 1<=n,m<=200000,1<=ai,bj,dj<=10^9,一定有"1"詢問
這題解法還是挺巧妙的
先考慮暴力
對於水平面高度為x
當h[i-1] < x <= h[i]時 ans++
正解:
觀察暴力, 對於h[i], h[i-1] 我們就給ans[h[i-1]+1 ~ h[i]] 加1
那麼我們可以先對所有高度離散化一下,再搞一顆樹狀陣列或線段樹, 區間修改單點詢問
#includeusing namespace std;
const int n = 200010;
struct node
}h[n<<1];
struct question q[n];
int a[n];
#define lowbit(x) (x&(-x))
int t[n<<1], n, m, s;
inline void add(int x, int k)
return ;
}inline int get(int x)
return sum;
}int main()
for (int i = 1; i <= m; i++)
sort(h+1, h+1+n+m);
s = 0;
for (int i = 1; i <= m+n; i++)
for (int i = 1; i <= n; i++)
if (a[i] > a[i-1]) add(a[i-1]+1, 1), add(a[i]+1, -1);
for (int i = 1; i <= m; i++)
} return 0;
}
洛谷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...