社区讨论
刚学OI的萌新求助KD-Tree近邻查询
P2093[国家集训队] JZPFAR参与者 2已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lo378k1y
- 此快照首次捕获于
- 2023/10/24 01:56 2 年前
- 此快照最后确认于
- 2023/10/24 01:56 2 年前
开O2 50 ,不开O2T没(
主要问题应该在查询那一部分,建树部分最大的点只要100ms应该没啥影响(
求大佬们帮捉虫QAQ
悬赏一个关注(忘记的话记得找我(
CPP
#include <iostream>
#include <cstdio>
#include <math.h>
#include <algorithm>
#include <istream>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <string.h>
#include <map>
#include <unordered_map>
#include <random>
#include <bitset>
#define int long long
//#define double long double
#define p1(x) x.first
#define p2(x) x.second
#define i128 __int128_t
//#pragma GCC optimize(2)
#define w(x) t[x].w
#define sw(x) t[x].sw
#define siz(x) t[x].siz
#define lc(x) t[x].c[0]
#define rc(x) t[x].c[1]
#define d(x) t[x].d
#define pii pair<int,int>
//若汁记好了以后再用Ctrl+C/+V你就是狗
using namespace std;
const int INF=2e18+7;
const double alpha=0.7;
struct node{
int mxx,mxy;
int mnx,mny;
int x,y;
int w,sw;
int siz;
bool d;
int c[2];
inline int mxd(int x,int y){
int dx=max(x-mnx,mxx-x),dy=max(y-mny,mxy-y);
return dx*dx+dy*dy;
}
inline int mnd(int x,int y){
int dx=min(max(0ll,mnx-x),max(0ll,x-mxx)),dy=min(max(0ll,mny-y),max(0ll,y-mxy));
return dx*dx+dy*dy;
}
inline int dt(int px,int py){
int dx=(px-x),dy=py-y;
return dx*dx+dy*dy;
}
}t[200300];
inline void upd(int x){
t[x].mxx=max(t[x].x,max(t[lc(x)].mxx,t[rc(x)].mxx));
t[x].mxy=max(t[x].y,max(t[lc(x)].mxy,t[rc(x)].mxy));
t[x].mnx=min(t[x].x,min(t[lc(x)].mnx,t[rc(x)].mnx));
t[x].mny=min(t[x].y,min(t[lc(x)].mny,t[rc(x)].mny));
siz(x)=siz(lc(x))+siz(rc(x))+1;
sw(x)=sw(lc(x))+sw(rc(x))+w(x);
}
int cnt,rt;
inline int nnd(int x,int y,int w,bool d){
t[++cnt]={x,y,x,y,x,y,w,w,1,d};;
return cnt;
}
int ct;
int p[200300];
inline void trs(int x){
p[++ct]=x;
if(lc(x))trs(lc(x));
if(rc(x))trs(rc(x));
}
inline bool cmpx(int a,int b){
return t[a].x<t[b].x;
}
inline bool cmpy(int a,int b){
return t[a].y<t[b].y;
}
inline int rb(int l,int r,bool d){
if(r<l)return 0;
if(l==r){
lc(p[l])=rc(p[l])=0;
siz(p[l])=1;
d(p[l])=d;
sw(p[l])=w(p[l]);
upd(p[l]);
return p[l];
}
int mid=l+r>>1;
nth_element(p+l,p+mid,p+r,d?cmpx:cmpy);
lc(p[mid])=rb(l,mid-1,!d);
rc(p[mid])=rb(mid+1,r,!d);
d(p[mid])=d;
upd(p[mid]);
return p[mid];
}
inline void RB(int &x){
ct=0;
trs(x);
int d=d(x);
x=rb(1,ct,d);
}
inline void chk(int &x){
if(max(siz(lc(x)),siz(rc(x)))>=siz(x)*alpha)RB(x);
}
inline void ins(int &x,int px,int py,int w,int d){
if(!x){
x=nnd(px,py,w,d);
return ;
}
if(d){
if(px<=t[x].x)ins(lc(x),px,py,w,!d);
else ins(rc(x),px,py,w,!d);
}
else{
if(py<=t[x].y)ins(lc(x),px,py,w,!d);
else ins(rc(x),px,py,w,!d);
}
upd(x);
chk(x);
}
inline int g(int x,int lx,int ly,int rx,int ry){
if(!x)return 0;
if(rx>=t[x].mxx&&ry>=t[x].mxy&&lx<=t[x].mnx&&ly<=t[x].mny)return sw(x);
int res=0;
if(rx>=t[x].x&&ry>=t[x].y&&lx<=t[x].x&&ly<=t[x].y)res=w(x);
if(d(x)){
if(lx<=t[lc(x)].mxx)res+=g(lc(x),lx,ly,rx,ry);
if(rx>=t[rc(x)].mnx)res+=g(rc(x),lx,ly,rx,ry);
}
else{
if(ly<=t[lc(x)].mxy)res+=g(lc(x),lx,ly,rx,ry);
if(ry>=t[rc(x)].mny)res+=g(rc(x),lx,ly,rx,ry);
}
return res;
}
priority_queue<pii,vector<pii>,greater<pii>>qmx;
priority_queue<pii>qmn;
inline void setmx(int k){
while(!qmx.empty())qmx.pop();
for(int i=1;i<=k;i++)
qmx.push({-INF,0});
}
inline void setmn(int k){
while(!qmn.empty())qmn.pop();
for(int i=1;i<=k;i++)
qmn.push({INF,0});
}
inline void gmx(int x,int px,int py){
if(!x)return ;
if(t[x].mxd(px,py)<=p1(qmx.top()))return ;
qmx.push({t[x].dt(px,py),-x});
qmx.pop();
gmx(lc(x),px,py);
gmx(rc(x),px,py);
}
inline void gmn(int x,int px,int py){
if(!x)return ;
if(t[x].mnd(px,py)<=p1(qmn.top()))return ;
qmn.push({t[x].dt(px,py),-x});
qmn.pop();
gmn(lc(x),px,py);
gmn(rc(x),px,py);
}
int n,q;
signed main(){
ios::sync_with_stdio(0);
// freopen("","r",stdin);
// freopen("","w",stdout);
t[0]={-INF,-INF,INF,INF,0,0,0,0,0};
cin>>n;
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
ins(rt,x,y,0,d(rt));
}RB(rt);
cin>>q;
while(q--){
int px,py,k;
cin>>px>>py>>k;
setmx(k);
gmx(rt,px,py);
cout<<-p2(qmx.top())<<endl;
}
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...