[Usaco2013 Nov]Crowded Cows

题目大意

N头牛在一个坐标轴上,每头牛有个高度。现给出一个距离值D。

如果某头牛在它的左边,在距离D的范围内,如果找到某个牛的高度至少是它的两倍,且在右边也能找到这样的牛的话。则此牛会感觉到不舒服。

问有多少头会感到不舒服。

题解

还有比这更裸的单调队列吗。。。。。。

#include 
#include
#include
using namespace std;
class Dread{
    private:
        bool isdigit(char ch) { return ch >= '0' && ch <= '9'; }
        bool isalpha(char ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); }
        void Getchar(int &tmp){
            char ch; tmp = 0; bool b = true;
            while (ch = getchar()){
				if (ch == '-') b = false;
				if (isdigit(ch)) break;
            }
			for (; isdigit(ch); ch = getchar()) tmp = tmp * 10 + ch - '0';
        	if (!b) tmp = -tmp;
		}
        void Getchar(char &tmp){
            while (tmp = getchar()) if (isalpha(tmp)) break;
        }
    public:
        int Int(){ int x; Getchar(x); return x; }
        char Ch(){ char x; Getchar(x); return x; }
}Read;
const int maxn = 50100;
struct point{
	int x, v;
}a[maxn];
int n, d;
void init(){
	n = Read.Int(), d = Read.Int();
	for (int i = 1; i <= n; i ++)
		a[i].x = Read.Int(), a[i].v = Read.Int();
}
int h[maxn][2], maxx[maxn];
bool cmp(point a, point b){ return a.x < b.x; }
void work(){
	int tt = 1, ww = 0;
	sort(a + 1, a + n + 1, cmp);
	for (int i = 1; i <= n; i ++){
		while (ww >= tt && a[i].x - h[tt][0] > d) tt ++;
		if (ww >= tt) maxx[i] = h[tt][1];
		while (ww >= tt && a[i].v > h[ww][1]) ww --;
		h[++ ww][0] = a[i].x, h[ww][1] = a[i].v;
	}
	memset(h, 0, sizeof(h));
	tt = 1, ww = 0;
	int ans = 0;
	for (int i = n; i >= 1; i --){
		while (ww >= tt && h[tt][0] - a[i].x> d) tt ++;
		if (ww >= tt && h[tt][1] >= a[i].v * 2 && maxx[i] >= a[i].v * 2) ans ++;
		while (ww >= tt && a[i].v > h[ww][1]) ww --;
		h[++ ww][0] = a[i].x, h[ww][1] = a[i].v;
	}
	printf("%d\n", ans);
}
int main(){
	init();
	work();
	return 0;
}


你可能感兴趣的:(水题,单调对列,单调对列,水题)