1. 程式人生 > >BZOJ_3476_[Usaco2014 Mar]The Lazy Cow_掃描線+切比雪夫距離

BZOJ_3476_[Usaco2014 Mar]The Lazy Cow_掃描線+切比雪夫距離

truct lease only NPU int content 線段樹 urn fin

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\n",ans);
}

BZOJ_3476_[Usaco2014 Mar]The Lazy Cow_掃描線+切比雪夫距離