现在的位置: 首页 > 综合 > 正文

SGU 394 Berhatton Bit 维护 Manhattan 距离

2018年04月25日 ⁄ 综合 ⁄ 共 1578字 ⁄ 字号 评论关闭

题意:平面图上有n(2<=n<=10^5)个点,每个点能覆盖住Manhattan距离为w范围内的点,如果一个点被覆盖的次数超过k次那么这个点就是能被删除的,

         问那些点能被删除。

题解:对于一个点能覆盖住的是一个以它为中心的菱形,将坐标轴逆时针旋转45度后每个点的覆盖关系不变,维护上下两条线的加减关系,Bit实现即可。


Sure原创,转载请注明出处

#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
using namespace std;
const int maxn = 100002;
struct node
{
    int xl,xr;
    long long y;
    int kind,id;
    bool operator < (const node &other) const
    {
        if(y == other.y)
        {
            return kind > other.kind;
        }
        return y < other.y;
    }
}line[maxn * 3];
int xx[maxn * 3],c[maxn * 3],ans[maxn],res[maxn];
int m,n,top,tot;

void add(int x1,int x2,long long yy,int kk,int ii)
{
    line[tot].xl = x1;
    line[tot].xr = x2;
    line[tot].y = yy;
    line[tot].kind = kk;
    line[tot].id = ii;
    tot++;
    return;
}

void read()
{
    memset(c,0,sizeof(c));
    top = tot = 0;
    int x,y,w;
    for(int i=0;i<n;i++)
    {
        scanf("%d %d %d",&x,&y,&w);
        add(x-y,x-y,(long long)x+y,0,i);
        add(x-y-w,x-y+w,(long long)x+y-w,1,-1);
        add(x-y-w,x-y+w,(long long)x+y+w,-1,-1);
        xx[top++] = x-y;
        xx[top++] = x-y-w;
        xx[top++] = x-y+w;
    }
    return;
}

void make()
{
    sort(line , line + tot);
    sort(xx , xx + top);
    top = unique(xx , xx + top) - xx;
    return;
}

int lowbit(int x)
{
    return x & (-x);
}

void update(int i,int val)
{
    while(i <= top)
    {
        c[i] += val;
        i += lowbit(i);
    }
    return;
}

int sum(int i)
{
    int res = 0;
    while(i > 0)
    {
        res += c[i];
        i -= lowbit(i);
    }
    return res;
}

void solve()
{
    for(int i=0;i<tot;i++)
    {
        int l = lower_bound(xx , xx + top , line[i].xl) - xx;
        int r = lower_bound(xx , xx + top , line[i].xr) - xx;
        if(l == r)
        {
            ans[line[i].id] = sum(l+1);
        }
        else
        {
            int val = line[i].kind;
            update(r+2,-val);
            update(l+1,val);
        }
    }
    top = 0;
    for(int i=0;i<n;i++)
    {
        if(ans[i] > m)
        {
            res[top++] = i+1;
        }
    }
    printf("%d\n",top);
    for(int i=0;i<top;i++)
    {
        if(i) printf(" ");
        printf("%d",res[i]);
    }
    if(top) puts("");
    return;
}

int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        read();
        make();
        solve();
    }
    return 0;
}

抱歉!评论已关闭.