BZOJ_3476_[Usaco2014 Mar]The Lazy Cow_扫描线+切比雪夫距离

BZOJ_3476_[Usaco2014 Mar]The Lazy Cow_扫描线+切比雪夫距离

Description

 It's a hot summer day, and Bessie the cow is feeling quite lazy. She wants to locate herself at a position in her field so that she can reach as much delicious grass as possible within only a short distance. There are N patches of grass (1 <= N <= 100,000) in Bessie's field. The ith such patch contains g_i units of grass (1 <= g_i <= 10,000) and is located at a distinct point (x_i, y_i) in the field (0 <= x_i, y_i <= 1,000,000). Bessie would like to choose a point in the field as her initial location (possibly the same point as a patch of grass, and possibly even a point with non-integer coordinates) so that a maximum amount of grass is within a distance of K steps from this location (1 <= K <= 2,000,000). When Bessie takes a step, she moves 1 unit north, south, east, or west of her current position. For example, to move from (0,0) to (3,2), this requires 5 total steps. Bessie does not need to take integer-sized steps -- for example, 1 total step could be divided up as half a unit north and half a unit east. Please help Bessie determine the maximum amount of grass she can reach, if she chooses the best possible initial location.

在二维平面有N个点。每个点都有个权值。

现在希望你选择某个点,如果其它点到这个点的距离不超过K。

则牛就可以吃到这个点的东西。

现在希望吃到的东西的权值越大越好。请求出这个值来。

Input

* Line 1: The integers N and K.

 * Lines 2..1+N: Line i+1 describes the ith patch of grass using 3 integers: g_i, x_i, y_i.

Output

* Line 1: The maximum amount of grass Bessie can reach within K steps, if she locates herself at the best possible initial position. 

Sample Input

4 3
7 8 6
3 0 0
4 6 0
1 4 2

INPUT DETAILS: Bessie is willing to take at most 3 steps from her initial position. There are 4 patches of grass. The first contains 7 units of grass and is located at position (8,6), and so on.

Sample Output

8


曼哈炖距离在处理‘距离不超过K’这种问题时比较麻烦,因为要维护一个斜45度的正方形。

于是逆时针旋转45度,使得x->x-y,y->x+y,转化为切比雪夫距离就只需要维护一个正方形。

然后就是扫描线的套路,设f[i]表示左下的纵坐标为i时的答案,用线段树维护y轴的f值。

每次相当于区间加和全局最大值。

注意这里y的范围是[0,2000000],空间要开够。

代码:

#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 2000050
#define inf 2000000
#define ls p<<1
#define rs p<<1|1
struct Point {
    int x,y,v;
    bool operator < (const Point &p) const {
        return x<p.x;
    }
}a[100050];
int n,t[N<<2],add[N<<2],K;
void pushdown(int p) {
    if(add[p]) {
        int d=add[p]; add[ls]+=d; add[rs]+=d;
        t[ls]+=d; t[rs]+=d; add[p]=0;
    }
}
void update(int l,int r,int x,int y,int v,int p) {
    if(x<=l&&y>=r) {
        t[p]+=v; add[p]+=v; return ;
    }
    pushdown(p);
    int mid=(l+r)>>1;
    if(x<=mid) update(l,mid,x,y,v,ls);
    if(y>mid) update(mid+1,r,x,y,v,rs);
    t[p]=max(t[ls],t[rs]);
}
int main() {
    scanf("%d%d",&n,&K); K<<=1;
    int i,x,y;
    for(i=1;i<=n;i++) {
        scanf("%d%d%d",&a[i].v,&x,&y); a[i].x=x-y; a[i].y=x+y;
    }
    sort(a+1,a+n+1);
    int ans=0;
    int j=1;
    for(i=1;i<=n;i++) {
        while(a[i].x-a[j].x>K) update(0,inf,max(0,a[j].y-K),a[j].y,-a[j].v,1),j++;
        update(0,inf,max(0,a[i].y-K),a[i].y,a[i].v,1);
        if(ans<t[1]) ans=t[1];
    }
    printf("%d
",ans);
}
原文地址:https://www.cnblogs.com/suika/p/9147787.html