51nod 1276 岛屿的数量

有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("\n");
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\n",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\n",h[ans]);
42     }
43     return 0;
44 }

 

posted @ 2018-09-02 10:38  starry_sky  阅读(248)  评论(0编辑  收藏  举报