題意:平面圖上有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;
}