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}。

分析:上网络编程课,闲着无聊,看了下题,第一直觉线段树,发现gg呀,然后第二感觉离线艹一下就好了,把query排下序,然后模拟了下,发现,删除的一个岛屿,如果两边都没删除CNT+1,两边都没有cnt-1,其余不变,然后就把
岛屿的高度也排下序,然后用刚才的结论模拟并且记录答案就好了

#include<bits/stdc++.h>
using namespace std;
const int maxn=50005;

int a[maxn],b[maxn],ax[maxn],bx[maxn];//岛屿高度  查询
int n,q;
bool l[maxn],r[maxn];//左右是否淹没
int ans[maxn];

bool cmp1(int i,int j){return a[i]<a[j];}
bool cmp2(int i,int j){return b[i]<b[j];}

int main(){
    ios::sync_with_stdio(false);
    cin>>n>>q;
    for(int i=1;i<=n;i++)cin>>a[i],ax[i]=i;
    for(int j=1;j<=q;j++)cin>>b[j],bx[j]=j;
    //排序
    sort(ax+1,ax+1+n,cmp1);
    sort(bx+1,bx+1+q,cmp2);
    //初始化
    memset(l,true,sizeof(l));
    memset(r,true,sizeof(r));
    l[1]=r[n]=0;
    int cnt=1;
    int L=1;
    for(int i=1;i<=q;i++){
        while(L<=n&&a[ax[L]]<=b[bx[i]]){
            int w=ax[L];
            if(l[w]&&r[w])cnt++;
            else if(!l[w]&&!r[w])cnt--;
            l[w+1]=r[w-1]=0;
            L++;
        }
        ans[bx[i]]=cnt;
    }
    for(int i=1;i<=q;i++)cout<<ans[i]<<endl;
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/jihe/p/5843647.html