BZOJ 1071: [SCOI2007]组队

把式子拆开后把min的部分放到右边
求出每个人的 S = A * height + B * speed
一个按 S 排序,一个按 speed 排序
然后枚举最小 speed 和最小 height,符合条件的是一个区间
双指针扫一下即可

#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define pii pair<int, int>
#define ll long long
#define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)
#define Edg int cnt=1,head[N],to[N*2],ne[N*2];void addd(int u,int v){to[++cnt]=v;ne[cnt]=head[u];head[u]=cnt;}void add(int u,int v){addd(u,v);addd(v,u);}
#define Edgc int cnt=1,head[N],to[N*2],ne[N*2],c[N*2];void addd(int u,int v,int w){to[++cnt]=v;ne[cnt]=head[u];c[cnt]=w;head[u]=cnt;}void add(int u,int v,int w){addd(u,v,w);addd(v,u,w);}
#define es(u,i,v) for(int i=head[u],v=to[i];i;i=ne[i],v=to[i])
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline char getc() {
	return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline int _() {
	int x = 0, f = 1; char ch = getc();
	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getc(); }
	while (ch >= '0' && ch <= '9') { x = x * 10ll + ch - 48; ch = getc(); }
	return x * f;
}
inline ll __() {
	ll x = 0, f = 1; char ch = getc();
	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getc(); }
	while (ch >= '0' && ch <= '9') { x = x * 10ll + ch - 48; ch = getc(); }
	return x * f;
}

const int N = 5555;
int n;
ll A, B, C;
struct Node {
	int h, s;
	ll sum;
	void read() {
		h = _(), s = _();
		sum = 1ll * A * h + 1ll * B * s;
	}
} p[N], q[N];
bool cmp1(const Node &a, const Node &b) { return a.h < b.h; }
bool cmp2(const Node &a, const Node &b) { return a.sum < b.sum; }
ll MinS, MaxS;

bool check(int x) {
	return x >= MinS && x <= MaxS;
}

int main() {
	n = _(), A = __(), B = __(), C = __();
	rep(i, 1, n + 1) p[i].read(), q[i] = p[i];
	std::sort(p + 1, p + n + 1, cmp1);
	std::sort(q + 1, q + n + 1, cmp2);
	int ans = 0;
	rep(i, 1, n + 1) {
		int cnt = 0, l = 0, r = 0;
		MinS = p[i].s, MaxS = MinS + C / B;
		rep(j, 1, n + 1) {
			int MinH = p[j].h;
			while (r < n && q[r + 1].sum <= A * MinH + B * MinS + C)
				cnt += check(q[++r].s);
			while (l < n && p[l + 1].h < MinH)
				cnt -= check(p[++l].s);
			ans = std::max(ans, cnt);
		}
	}
	printf("%d\n", ans);
	return 0;
}
posted @ 2020-02-19 17:14  Mrzdtz220  阅读(67)  评论(0)    收藏  举报