51nod 1276 【离线化】

思路1.:
离线处理;
具体就是把岛屿离线然后按照高度排序,把query按照从高到低排序,然后每次query只要从最高的岛屿开始找起,判断条件:如果他旁边都是没有被找过的(也就是默认是海),那么数量+1,如果两边都是岛屿,那么数量-1,我们不需要判断一边是岛屿,一边是海没意义
思路2.:
还有一个可以在线算答案
具体:
具体找出峰值谷值,用两个数组存一下,排序。然后每次二分找一下,就可以知道淹了多少个那些。。

贴我大哥的代码:


#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

pair<int,int> a[50010];
pair<int,int> b[50010];
bool vis[50010];
int ans[50010];
int main()
{
    int n, q;
    scanf("%d%d", &n, &q);
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d", &a[i].first);
        a[i].second = i;
    }
    for(int i = 1; i <= q; ++i)
    {
        scanf("%d", &b[i].first);
        b[i].second = i;
    }

    sort(a + 1, a + 1 + n);
    sort(b + 1, b + 1 + q, greater<pair<int, int> >());

    memset(vis, false, sizeof(vis));
    int e = n;
    int cnt = 0;
    for(int i = 1; i <= q; ++i)
    {
        while(e >= 1 && a[e].first > b[i].first)
        {
            if(!vis[ a[e].second - 1 ] && !vis[ a[e].second + 1 ])
                ++cnt;
            else if(vis[ a[e].second - 1 ] && vis[ a[e].second + 1 ])
                --cnt;
            vis[ a[e].second ] = true;
            --e;
        }
        ans[ b[i].second ] = cnt;
    }
    for(int i = 1;i <= q;++i)
        printf("%d\n", ans[i]);
    return 0;
}
posted @ 2016-08-31 23:42  see_you_later  阅读(117)  评论(0编辑  收藏  举报