有N个岛连在一起形成了一个大的岛屿,如果海平面上升超过某些岛的高度时,则这个岛会被淹没。原本的大岛屿则会分为多个小岛屿,如果海平面一直上升,则所有岛都会被淹没在水下。
给出N个岛的高度。然后有Q个查询,每个查询给出一个海平面的高度H,问当海平面高度达到H时,海上共有多少个岛屿。例如:
岛屿的高度为:{2, 1, 3, 2, 3}, 查询为:{0, 1, 3, 2}。
当海面高度为0时,所有的岛形成了1个岛屿。
当海面高度为1时,岛1会被淹没,总共有2个岛屿{2} {3, 2, 3}。
当海面高度为3时,所有岛都会被淹没,总共0个岛屿。
当海面高度为2时,岛0, 1, 3会被淹没,总共有2个岛屿{3} {3}。
Input
第1行:2个数N, Q中间用空格分隔,其中N为岛的数量,Q为查询的数量(1 <= N, Q <= 50000)。 第2 - N + 1行,每行1个数,对应N个岛屿的高度(1 <= A[i] <= 10^9)。 第N + 2 - N + Q + 1行,每行一个数,对应查询的海平面高度(1 <= Q[i] <= 10^9)。
Output
输出共Q行,对应每个查询的岛屿数量。
Input示例
5 4 2 1 3 2 3 0 1 3 2
Output示例
1 2 0 2
淹没山谷,岛屿+1 淹没山峰,岛屿-1 ,根据这个写,先预处理一下,岛的数量最大5e4,先计算每个高度被淹没后存在多少岛屿,然后询问的话二次查找就行。
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define lson l,m,rt<<|1 4 #define rson m+1,r,rt<<1|1 5 const int N = 5e4+10; 6 using namespace std; 7 int n, q, cnt = 1; 8 int a[N], vis[N],h[N]; 9 vector<int> vs[N]; 10 map<int,int> mp; 11 int main() { 12 scanf("%d%d", &n, &q); 13 for(int i = 1; i <= n; i ++) { 14 cin >> a[i]; 15 if(!mp.count(a[i])) mp[a[i]] = cnt++; 16 vs[mp[a[i]]].push_back(i); 17 } 18 sort(a+1,a+1+n); 19 int m = 2; 20 for(int i = 2; i <= n; i ++) { 21 if(a[i]!=a[i-1]) a[m++] = a[i]; 22 } 23 // for(int i = 1; i < m; i ++) printf("%d ",a[i]);printf(" "); 24 int ans = 1; 25 h[0] = vis[0] = vis[n+1] = 1; 26 for(int i = 1; i < m; i ++) { 27 for(int j = 0; j < vs[mp[a[i]]].size(); j ++) { 28 int id = vs[mp[a[i]]][j]; 29 if(vis[id-1]&&vis[id+1]) ans--; 30 if(!vis[id-1]&&!vis[id+1]) ans++; 31 vis[id] = 1; 32 } 33 h[i] = ans; 34 } 35 // for(int i = 1; i < m; i ++) printf("%d %d ",i,h[i]); 36 while(q--) { 37 int x; 38 scanf("%d", &x); 39 int ans = lower_bound(a+1,a+m,x)-a; 40 if(a[ans] != x) ans--; 41 printf("%d ",h[ans]); 42 } 43 return 0; 44 }