【BZOJ 2716/2648】 [Violet 3]天使玩偶
来源:互联网 发布:server2012 mysql集群 编辑:程序博客网 时间:2024/05/01 14:12
2716: [Violet 3]天使玩偶
kd-tree模板题。
①首先依次按照每一维(即先按照
先求出以当前维数为关键字的中间点是谁(用到nth_element这个函数,可以直接把排名为
为了一会儿查询中求估价函数方便,需要记录一下当前节点的子树中各维的极值(max,min)
②插入操作与splay的插入操作同理。
③询问操作的本质是搜索+用估价函数剪枝(估价函数的结果一定比实际最优解小),先搜索更优的,用更优的那个子树更新答案;判断次优的子树的估价函数是否小于当前答案,可以发现这个概率是比较小的,进入次优子树搜索的概率就小一些。
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#define inf 0x3f3f3f3f#define M 2000005using namespace std;int k,x[2],root,ans,now,n,m;struct node{ int ma[2],mi[2],d[2],l,r;}t[M];void read(int &tmp){ tmp=0; char ch=getchar(); int fu=1; for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') fu=-1; for (;ch>='0'&&ch<='9';ch=getchar()) tmp=tmp*10+ch-'0'; tmp*=fu;}bool cmp(node a,node b){ if (a.d[now]==b.d[now]) return a.d[now^1]<b.d[now^1]; return a.d[now]<b.d[now];}void Update(int x){ int l=t[x].l,r=t[x].r; for (int i=0;i<2;i++) { t[x].ma[i]=max(t[x].ma[i],max(t[l].ma[i],t[r].ma[i])); t[x].mi[i]=min(t[x].mi[i],min(t[l].mi[i],t[r].mi[i])); }}int Build(int l,int r,int k){ int m=(l+r)>>1; now=k; nth_element(t+l+1,t+m+1,t+r+1,cmp); for (int i=0;i<2;i++) t[m].ma[i]=t[m].mi[i]=t[m].d[i]; if (l!=m) t[m].l=Build(l,m-1,k^1); if (r!=m) t[m].r=Build(m+1,r,k^1); Update(m); return m;}void Insert(int now){ int k=0,p=root; while (1) { for (int i=0;i<2;i++) { t[p].ma[i]=max(t[p].ma[i],t[now].ma[i]); t[p].mi[i]=min(t[p].mi[i],t[now].mi[i]); } if (t[now].d[k]>=t[p].d[k]) { if (!t[p].r) { t[p].r=now; return; } else p=t[p].r; } else { if (!t[p].l) { t[p].l=now; return; } else p=t[p].l; } k=k^1; }}int Dis(int p){ return abs(t[p].d[0]-x[0])+abs(t[p].d[1]-x[1]);}int Get(int p){ int ans=0; for (int i=0;i<2;i++) ans+=max(0,t[p].mi[i]-x[i])+max(0,x[i]-t[p].ma[i]); return ans;}void Query(int p){ if (!p) return; int d0=Dis(p),dl=Get(t[p].l),dr=Get(t[p].r); if (d0<ans) ans=d0; if (dl<dr) { if (dl<ans) Query(t[p].l); if (dr<ans) Query(t[p].r); } else { if (dr<ans) Query(t[p].r); if (dl<ans) Query(t[p].l); }}int main(){ scanf("%d%d",&n,&m); t[0].ma[0]=t[0].ma[1]=-inf,t[0].mi[0]=t[0].mi[1]=inf; for (int i=1;i<=n;i++) read(t[i].d[0]),read(t[i].d[1]); root=Build(1,n,0); for (int i=1;i<=m;i++) { read(k),read(x[0]),read(x[1]); if (k==1) { n++; for (int j=0;j<2;j++) t[n].ma[j]=t[n].mi[j]=t[n].d[j]=x[j]; Insert(n); } else { ans=inf; Query(root); printf("%d",ans); putchar('\n'); } } return 0;}
3 1
- 【BZOJ 2716/2648】 [Violet 3]天使玩偶
- BZOJ 2716 [Violet 3]天使玩偶 KDtree
- 【BZOJ 2716&2648】[Violet 3]天使玩偶 k-d tree
- 【BZOJ 2716/2648】 [Violet 3]天使玩偶 SJY摆棋子
- BZOJ 2716 Violet 3 天使玩偶 CDQ分治
- bzoj 2716: [Violet 3]天使玩偶(cdq分治)
- [BZOJ]2716: [Violet 3]天使玩偶 CDQ分治+树状数组
- [KD-TREE] BZOJ 2648 SJY摆棋子 & BZOJ 2716 [Violet 3]天使玩偶
- BZOJ 2648: SJY摆棋子/BZOJ 2716: [Violet 3]天使玩偶 kdtree
- BZOJ 2648 SJY摆棋子 / 2716 Violet 3 天使玩偶 K-D树
- BZOJ 2648/2716 SJY摆棋子/[Violet 3]天使玩偶 kd tree
- bzoj2716: [Violet 3]天使玩偶
- 【bzoj 2716】[Violet 3]天使玩偶 (cdq分治+树状数组)
- [BZOJ 2716]天使玩偶
- 2648: SJY摆棋子/2716: [Violet 3]天使玩偶 K-D tree
- 2716: [Violet 3]天使玩偶&&2648: SJY摆棋子|K-DTree
- [BZOJ2716][Violet 3]天使玩偶 && kdtree
- [KDTree] [BZOJ2716] [Violet 3] 天使玩偶
- Android编程style, include, merge标签
- 【ThinkingInJava】38、泛型数组转化,传递一个类型标识
- TexturePacker 命令行打包图片shell脚本
- IOS-IOS中定时器NSTimer的开启与关闭
- HTML <EM>强调标签元素
- 【BZOJ 2716/2648】 [Violet 3]天使玩偶
- 【ThinkingInJava】39、对于<?>和原生类型的判断
- ueditor1.4.3配置过程(包含单独上传文件以及图片的使用)
- 汇编相关(ASCII码字符表 DEBUG命令 BIOS功能调用表 DOS功能调用表 汇编语言错误信息表)
- IntelliJ IDEA 14 注册码
- Sicily 2016. Emergent escape
- 设计模式---创建型模式
- Sicily 14514. Bread Sorting
- html基础学习之视频播放