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

浙公网安备 33010602011771号