P4169 [Violet]天使玩偶/SJY摆棋子(CDQ分治、暴力)
2021/12/12 23:22:50
本文主要是介绍P4169 [Violet]天使玩偶/SJY摆棋子(CDQ分治、暴力),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
解析
之前用KDtree做的一道题
由于懒不想再码一遍了
考虑CDQ分治
关键就是如何拿掉绝对值
如果只维护左下角的,显然就是一个经典的三维偏序问题了
但是本题不一定在左下角,也可能在左上、右下、右上
怎么办?
把坐标翻转翻转直接暴力做四遍即可
有昨晚CFE题暴力枚举做36遍那味了
代码
既然没写,哪里有代码啊
那我就把之前的KDtree贴一下吧
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=2e6+100; const int M=1050; const int mod=998244353; inline ll read(){ ll x=0,f=1;char c=getchar(); while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} return x*f; } int n,m,tot,num; int rub[N],top; int F; struct point{int x[2];}p[N]; #define dis(a,b) (abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1])) bool operator < (const point a,point b){return a.x[F]<b.x[F];} struct node{ int mn[2],mx[2],ls,rs,siz; point o; }tr[N]; int New(point u){ int x=top?rub[top--]:++tot;tr[x].o=u;tr[x].siz=1; tr[x].mn[0]=tr[x].mx[0]=u.x[0]; tr[x].mn[1]=tr[x].mx[1]=u.x[1]; tr[x].ls=tr[x].rs=0; return x; } void pushup(int k){ int l=tr[k].ls,r=tr[k].rs; for(int i=0;i<=1;i++){ tr[k].mn[i]=tr[k].mx[i]=tr[k].o.x[i]; if(l){ tr[k].mn[i]=min(tr[k].mn[i],tr[l].mn[i]); tr[k].mx[i]=max(tr[k].mx[i],tr[l].mx[i]); } if(r){ tr[k].mn[i]=min(tr[k].mn[i],tr[r].mn[i]); tr[k].mx[i]=max(tr[k].mx[i],tr[r].mx[i]); } } tr[k].siz=tr[l].siz+tr[r].siz+1; return; } void print(int k){ printf("k=%d (%d %d) ls=%d rs=%d mn=(%d %d) mx=(%d %d)\n",k,tr[k].o.x[0],tr[k].o.x[1],tr[k].ls,tr[k].rs,tr[k].mn[0],tr[k].mn[1],tr[k].mx[0],tr[k].mx[1]); } int build(int l,int r,int f){ int mid=(l+r)>>1; F=f;nth_element(p+l,p+mid,p+r+1); int k=New(p[mid]); if(l<mid) tr[k].ls=build(l,mid-1,f^1); if(mid<r) tr[k].rs=build(mid+1,r,f^1); pushup(k); //print(k); return k; } void pia(int k,int num){ if(tr[k].ls) pia(tr[k].ls,num); p[num+tr[tr[k].ls].siz+1]=tr[k].o; if(tr[k].rs) pia(tr[k].rs,num+tr[tr[k].ls].siz+1); rub[++top]=k; return; } double A=0.95; void check(int &k,int f){ if(tr[tr[k].ls].siz>tr[k].siz*A||tr[tr[k].rs].siz>tr[k].siz*A){ pia(k,0);k=build(1,tr[k].siz,f);//printf("ok"); } return; } void insert(int &k,int f,point u){ if(!k){ k=New(u);return; } if(u.x[f]<=tr[k].o.x[f]) insert(tr[k].ls,f^1,u); else insert(tr[k].rs,f^1,u); pushup(k);check(k,f); return; } int getdis(point o,int k){ int res=0; for(int i=0;i<=1;i++){ res+= max(0,tr[k].mn[i]-o.x[i])+max(0,o.x[i]-tr[k].mx[i]); } return res; } int ans; //void query(int k,point now){ // int dl,dr,l=tr[k].ls,r=tr[k].rs; // ans=min(ans,dis(tr[k].o,now)); // if(l) dl=getdis(now,tr[k].ls); // if(r) dr=getdis(now,tr[k].rs); // if(dl<dr){ // if(l&&dl<ans) query(tr[k].ls,now); // if(r&&dr<ans) query(tr[k].rs,now); // } // else{ // if(r&&dr<ans) query(tr[k].rs,now); // if(l&&dl<ans) query(tr[k].ls,now); // } //} void query(int k,point tmp) {//查询 ans=min(ans,dis(tmp,tr[k].o)); int dl=INT_MAX,dr=INT_MAX; if(tr[k].ls) dl=getdis(tmp,tr[k].ls); if(tr[k].rs) dr=getdis(tmp,tr[k].rs); if(dl<dr) { if(dl<ans) query(tr[k].ls,tmp); if(dr<ans) query(tr[k].rs,tmp); } else { if(dr<ans) query(tr[k].rs,tmp); if(dl<ans) query(tr[k].ls,tmp); } } int r; int main(){ // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); n=read();m=read(); for(int i=1;i<=n;i++){ p[i]=(point){read(),read()}; } r=build(1,n,0); for(int i=1;i<=m;i++){ int op=read(),x=read(),y=read(); point o=(point){x,y}; if(op==1){ insert(r,0,o); } else{ ans=2e9; query(r,o); printf("%d\n",ans); } } return 0; } /* 5 1 725 771 285 344 155 16 674 79 674 710 2 427 398 */
这篇关于P4169 [Violet]天使玩偶/SJY摆棋子(CDQ分治、暴力)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-27文件掩码什么意思?-icode9专业技术文章分享
- 2024-12-27如何使用循环来处理多个订单的退款请求,代码怎么写?-icode9专业技术文章分享
- 2024-12-27VSCode 在编辑时切换到另一个文件后再切回来如何保持在原来的位置?-icode9专业技术文章分享
- 2024-12-27Sealos Devbox 基础教程:使用 Cursor 从零开发一个 One API 替代品 审核中
- 2024-12-27TypeScript面试真题解析与实战指南
- 2024-12-27TypeScript大厂面试真题详解与解析
- 2024-12-26怎么使用nsenter命令进入容器?-icode9专业技术文章分享
- 2024-12-26导入文件提示存在乱码,请确定使用的是UTF-8编码怎么解决?-icode9专业技术文章分享
- 2024-12-26csv文件怎么设置编码?-icode9专业技术文章分享
- 2024-12-25TypeScript基础知识详解