题目大意
不想讲。
做法
可以转45度角变成切比雪夫距离,这样图像是正方形。
先用bfs找出所有可以踩到的点(可以对每行每列维护set,一个被bfs到的直接在两颗平衡树中删去)。
然后对每个能被踩到的点统计与其切比雪夫距离为d的点的个数(可以对每行每列维护vector并二分)。
最后答案除以2。
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=100000+10;
const ll inf=40000000000;
map<ll,int> row,col;
struct dong{
int id,y;
ll x;
friend bool operator <(dong a,dong b){
return a.x<b.x||a.x==b.x&&a.id<b.id;
}
} zlt;
set<dong> ro[maxn],co[maxn];
set<dong>::iterator it;
vector<dong> rw[maxn],cl[maxn];
vector<dong>::iterator ti;
int x[maxn],y[maxn],dl[maxn];
ll p[maxn],q[maxn];
bool bz[maxn];
int i,j,k,l,t,n,m,xx,yy,a,b,head,tail,now,tot,top;
ll ans,d;
void del(int id){
int xx=x[id],yy=y[id];
zlt.id=id;zlt.x=q[yy];
ro[xx].erase(ro[xx].find(zlt));
zlt.id=id;zlt.x=p[xx];
co[yy].erase(co[yy].find(zlt));
}
void ins(int x,ll l,ll r){
int y;
dong wxh;
while (1){
wxh.id=0;wxh.x=l;
it=ro[x].lower_bound(wxh);
if (it==ro[x].end()) break;
zlt=*it;
if (zlt.x>r) break;
y=zlt.id;
bz[y]=1;
dl[++tail]=y;
del(y);
}
}
void inse(int x,ll l,ll r){
int y;
dong wxh;
while (1){
wxh.id=0;wxh.x=l;
it=co[x].lower_bound(wxh);
if (it==co[x].end()) break;
zlt=*it;
if (zlt.x>r) break;
y=zlt.id;
bz[y]=1;
dl[++tail]=y;
del(y);
}
}
void ask(int x,ll l,ll r){
/*int t=lower_bound(rw[x],rw[x]+s,r+1)-rw[x];
t-=lower_bound(rw[x],rw[x]+s,l)-rw[x];*/
dong wxh;
wxh.id=0;wxh.x=r+1;
zlt=*(lower_bound(rw[x].begin(),rw[x].end(),wxh));
int t=zlt.y;
wxh.id=0;wxh.x=l;
zlt=*(lower_bound(rw[x].begin(),rw[x].end(),wxh));
t-=zlt.y;
ans+=(ll)t;
}
void query(int x,ll l,ll r){
/*int s=cl[x].size();
int t=lower_bound(cl[x],cl[x]+s,r+1)-cl[x];
t-=lower_bound(cl[x],cl[x]+s,l)-cl[x];
ans+=(ll)t;*/
dong wxh;
wxh.id=0;wxh.x=r+1;
zlt=*(lower_bound(cl[x].begin(),cl[x].end(),wxh));
int t=zlt.y;
wxh.id=0;wxh.x=l;
zlt=*(lower_bound(cl[x].begin(),cl[x].end(),wxh));
t-=zlt.y;
ans+=(ll)t;
}
int main(){
scanf("%d%d%d",&n,&a,&b);
fo(i,1,n){
scanf("%d%d",&j,&k);
p[i]=x[i]=j-k;
q[i]=y[i]=j+k;
}
sort(p+1,p+n+1);
tot=unique(p+1,p+n+1)-p-1;
fo(i,1,n) x[i]=lower_bound(p+1,p+tot+1,x[i])-p;
sort(q+1,q+n+1);
top=unique(q+1,q+n+1)-q-1;
fo(i,1,n) y[i]=lower_bound(q+1,q+top+1,y[i])-q;
fo(i,1,tot) row[p[i]]=i;
fo(i,1,top) col[q[i]]=i;
d=max(abs(p[x[a]]-p[x[b]]),abs(q[y[a]]-q[y[b]]));
fo(i,1,n){
zlt.id=i;zlt.x=q[y[i]];
ro[x[i]].insert(zlt);
rw[x[i]].push_back(zlt);
zlt.id=i;zlt.x=p[x[i]];
co[y[i]].insert(zlt);
cl[y[i]].push_back(zlt);
/*rw[x[i]].push_back(q[y[i]]);
cl[y[i]].push_back(p[x[i]]);*/
}
fo(i,1,tot){
sort(rw[i].begin(),rw[i].end());
zlt.id=0;zlt.x=inf;
rw[i].push_back(zlt);
t=rw[i].size();
fo(j,0,t-1) rw[i][j].y=j;
}
fo(i,1,top){
sort(cl[i].begin(),cl[i].end());
zlt.id=0;zlt.x=inf;
cl[i].push_back(zlt);
t=cl[i].size();
fo(j,0,t-1) cl[i][j].y=j;
}
head=0;
dl[tail=1]=a;
bz[a]=1;
del(a);
while (head<tail){
now=dl[++head];
xx=x[now];yy=y[now];
if (row[p[xx]-d]) ins(row[p[xx]-d],q[yy]-d,q[yy]+d);
if (row[p[xx]+d]) ins(row[p[xx]+d],q[yy]-d,q[yy]+d);
if (col[q[yy]-d]) inse(col[q[yy]-d],p[xx]-d,p[xx]+d);
if (col[q[yy]+d]) inse(col[q[yy]+d],p[xx]-d,p[xx]+d);
}
fo(i,1,n)
if (bz[i]){
xx=x[i];yy=y[i];
if (row[p[xx]-d]) ask(row[p[xx]-d],q[yy]-d+1,q[yy]+d);
if (col[q[yy]-d]) query(col[q[yy]-d],p[xx]-d,p[xx]+d-1);
if (row[p[xx]+d]) ask(row[p[xx]+d],q[yy]-d,q[yy]+d-1);
if (col[q[yy]+d]) query(col[q[yy]+d],p[xx]-d+1,p[xx]+d);
}
ans/=2;
printf("%lld\n",ans);
}