BZOJ : [Usaco2013 Nov]Crowded 单调队列

正反两遍个来一次单调队列 DP 即可. 

Code:

#include<cstdio>
#include<deque>
#include<algorithm>
using namespace std;
const int maxn = 50000+3;
int mark[maxn];
struct Node{
    long long pos,height;
    Node(long long pos=0,long long height=0):pos(pos),height(height){}
    bool operator<(Node b)const{
        if(b.pos == pos)return height > b.height;
        return  pos<b.pos;
    }
}A[maxn];
deque<Node>Q;
int main(){
   // freopen("in.txt","r",stdin);
    int n;
    long long d;
    scanf("%d%lld",&n,&d);
    for(int i =1;i<=n;++i)
    {
        long long a,b;
        scanf("%lld%lld",&a,&b);
        A[i]=Node(a,b);
    }
    sort(A+1,A+1+n);
    int cnt = 0;
    for(int i = 1;i <= n; ++i)
    {
        long long cur_pos = A[i].pos-d;
        long long cur_height = A[i].height;

        while(!Q.empty()&&Q.front().pos < cur_pos)Q.pop_front();

        while(!Q.empty()&&Q.back().height <= cur_height)Q.pop_back();
        Q.push_back(A[i]);
        if(Q.front().height >= A[i].height*2)mark[i] = 1;
    }
    while(!Q.empty())Q.pop_back();
    for(int i =n;i>=1;--i){
        long long cur_pos = A[i].pos + d;
        long long cur_height = A[i].height;
        while(!Q.empty()&&Q.front().pos > cur_pos)Q.pop_front();

        while(!Q.empty()&&Q.back().height <= cur_height)Q.pop_back();
        Q.push_back(A[i]);
        if(Q.front().height >= A[i].height*2&&mark[i])++cnt;
    }
    printf("%d",cnt);
    return 0;
}

  

posted @ 2019-06-17 18:53  EM-LGH  阅读(137)  评论(0编辑  收藏  举报