有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; }