您的位置:首页 > 其它

bzoj 2648: SJY摆棋子

2018-07-15 11:53 375 查看

Description

这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。

Solution

\(kdtree\)

比普通的 \(kdtree\) 差不多,多了一个插入操作,像平衡树一样插入就行了

这样可能会复杂度退化,可以使用定期重构的方法来稳定复杂度

实测加上定期重构之后反而变慢了,此题数据范围不宜这么做

#include<bits/stdc++.h>
using namespace std;
template<class T>void gi(T &x){
int f;char c;
for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
}
const int N=1e6+10,inf=1e9;
int n,D,Q,B,rt,cnt,ans,op;
struct data{
int a[2],mn[2],mx[2],l,r;
inline int& operator [](int x){return a[x];}
}t
,e;
inline bool operator <(data p,data q){return p[D]<q[D];}
inline void upd(int o){
int ls=t[o].l,rs=t[o].r;
for(int i=0;i<2;i++){
t[o].mx[i]=max(t[o].mx[i],max(t[ls].mx[i],t[rs].mx[i]));
t[o].mn[i]=min(t[o].mn[i],min(t[ls].mn[i],t[rs].mn[i]));
}
}
inline int build(int l,int r,int k){
D=k;
int mid=(l+r)>>1,o=mid;
nth_element(t+l,t+mid,t+r+1);
for(int i=0;i<2;i++)t[o].mx[i]=t[o].mn[i]=t[o][i];
if(l<mid)t[o].l=build(l,mid-1,k^1);
if(r>mid)t[o].r=build(mid+1,r,k^1);
return upd(o),o;
}
inline int ins(int o,int k){
if(!o)return cnt;
if(e[k]>t[o][k])t[o].r=ins(t[o].r,k^1);
else t[o].l=ins(t[o].l,k^1);
return upd(o),o;
}
inline int dis(int o){return abs(t[o][0]-e[0])+abs(t[o][1]-e[1]);}
inline int cmin(int o){
if(!o)return 0;
int ret=0;
for(int i=0;i<2;i++)ret+=max(0,e[i]-t[o].mx[i])+max(0,t[o].mn[i]-e[i]);
return ret;
}
inline void qmin(int o){
if(!o)return ;
int dl=cmin(t[o].l),dr=cmin(t[o].r),dc=dis(o);
ans=min(ans,dc);
if(dl<dr){
if(dl<ans)qmin(t[o].l);
if(dr<ans)qmin(t[o].r);
}
else{
if(dr<ans)qmin(t[o].r);
if(dl<ans)qmin(t[o].l);
}
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
cin>>n>>Q;B=sqrt(n+Q);cnt=n;
for(int i=1;i<=n;i++)gi(t[i][0]),gi(t[i][1]);
for(int i=0;i<=1;i++)t[0].mx[i]=-inf,t[0].mn[i]=inf;
rt=build(1,n,0);
while(Q--){
gi(op);gi(e[0]);gi(e[1]);
if(op==1){
t[++cnt]=e;
for(int i=0;i<2;i++)t[cnt].mx[i]=t[cnt].mn[i]=e[i];
rt=ins(rt,0);
}
else ans=inf,qmin(rt),printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: