Description
夏天很热,贝茜越发地懒散了。她想要使自己位于她的田里一个尽可能在短距离内够到美味的青草的位置。
贝茜的田里有N(1<= N <=100,000)片青草。第i 片有gi 单位的青草(1<=gi<=10,000),并且它唯一地位于田里坐标为(xi,yi)(0<= xi, yi<=1,000,000)的点。贝茜想要在田地里选一个点作为她的初始位置(可能和某一片青草的
位置重合,也可能初始位置的坐标并不是整数) 以便从这个位置出发走K(1<= K<= 2,000,000)步的距离以内有尽可能最多的青草。
当贝茜踏出一步,她从她现在的位置向北,南,东或西移动一单位距离。举个例子,为了从(0; 0) 走到(3; 2),贝茜总共需要5 步。但是贝茜不需要总是走整数步——例如,合起来的一步可以分为向北迈出的半步和向西迈出的半步。
请帮助贝茜确定,如果她选择了最佳的初始位置,她能够到的最大青草量。
对于10% 的数据,有N <=10。
Solution
数据规模非常不良心
发现走的是曼哈顿距离,那么旋转一下缩放
2–√
2
倍得到新的坐标,我们要找一个边长为2k的正方形使得内部所含g之和最大
这样想比较麻烦,可以考虑每个点的贡献。显然一个点(x,y)能贡献以(x-k,y-k)为左下角,(x+k,y+k)为右上角的一个正方形,那么就是求n个正方形交的最大值咯,离散一下就是扫描线的基本应用
Code
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <vector>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef double db;
const int N=200005;
const db pi=3.1415926535897932;
struct pos {int x,y; int c;} p[N];
struct line {int x; int up,down,c;};
int b[N],m;
int max[N*4],lazy[N*4];
int n,sizeA,sizeB;
line vec[N];
bool cmp(line a,line b) {
return a.x<b.x;
}
int rank(int x) {
return std:: lower_bound(b+1,b+sizeB+1,x)-b;
}
void pre_work() {
rep(i,1,n) {
b[i*2-1]=p[i].y+m; b[i*2]=p[i].y-m;
}
std:: sort(b+1,b+n*2+1);
sizeB=std:: unique(b+1,b+n*2+1)-b-1;
rep(i,1,n) {
line tmp;
tmp.x=p[i].x-m; tmp.c=p[i].c;
tmp.up=rank(p[i].y+m); tmp.down=rank(p[i].y-m);
vec[i*2-1]=tmp;
tmp.x=p[i].x+m+1; tmp.c=-p[i].c;
vec[i*2]=tmp;
}
std:: sort(vec+1,vec+n*2+1,cmp);
}
void push_down(int now) {
if (!lazy[now]) return ;
lazy[now<<1]+=lazy[now];
lazy[now<<1|1]+=lazy[now];
max[now<<1]+=lazy[now];
max[now<<1|1]+=lazy[now];
lazy[now]=0;
}
void modify(int now,int tl,int tr,int l,int r,int v) {
if (tl==l&&tr==r) {
lazy[now]+=v;
max[now]+=v;
return ;
}
push_down(now);
int mid=(tl+tr)>>1;
if (r<=mid) modify(now<<1,tl,mid,l,r,v);
else if (l>mid) modify(now<<1|1,mid+1,tr,l,r,v);
else {
modify(now<<1,tl,mid,l,mid,v);
modify(now<<1|1,mid+1,tr,mid+1,r,v);
}
max[now]=std:: max(max[now<<1],max[now<<1|1]);
}
void solve() {
int ans=0;
rep(i,1,n*2) {
int j=vec[i].x;
while (vec[i].x==j) {
modify(1,1,sizeB,vec[i].down,vec[i].up,vec[i].c);
i++;
}
i--;
ans=std:: max(ans,max[1]);
}
printf("%d\n", ans);
}
int main(void) {
freopen("data.in","r",stdin);
scanf("%d%d",&n,&m);
rep(i,1,n) {
int x,y; scanf("%d%d%d",&p[i].c,&x,&y);
p[i].x=x+y; p[i].y=y-x;
}
pre_work();
solve();
return 0;
}