博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 2716: [Violet 3]天使玩偶 [CDQ分治]
阅读量:7113 次
发布时间:2019-06-28

本文共 3320 字,大约阅读时间需要 11 分钟。

题意:

维护二维点集P,支持以下两个操作

(1)插入点(x,y)
(2)给定询问(x,y),求点集中离询问点最近的点
距离定义为曼哈顿距离
Dis(P1,P2)=|x1-x2|+|y1-y2|
n,m<=500000
x,y<=1000000


时间,$x$,$y$

$CDQ$分治里需要四个象限分类讨论,树状数组维护最大值

然后有两个象限是后缀和

然后跟$PoPoQQQ$学了一个神奇的技巧,树状数组加一个时间戳,就可以不用每次清空之前的操作了

 

#include 
#include
#include
#include
using namespace std;typedef long long ll;const int N=1e6+5,M=1e6+5,INF=1e9;inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}int cc[20];inline void put(int x){ if(x==0) putchar('0'); else{ int top=0; while(x) cc[++top]=x%10,x/=10; for(int i=top;i>=1;i--) putchar('0'+cc[i]); } putchar('\n');}int n,m,qid,maxVal=-INF;struct Operation{ int x,y,op,id,qid; Operation():op(0){}}a[N],t[N];int c[M],mark[M],cl;inline int lowbit(int x){
return x&-x;}inline void upd(int p,int v){ for(;p<=maxVal;p+=lowbit(p)){ if(mark[p]!=cl) mark[p]=cl,c[p]=v; else c[p]=max(c[p],v); }}inline int que(int p){ int re=-INF; for(;p;p-=lowbit(p)) if(mark[p]==cl) re=max(re,c[p]); return re;}inline void upd2(int p,int v){ for(;p;p-=lowbit(p)){ if(mark[p]!=cl) mark[p]=cl,c[p]=v; else c[p]=max(c[p],v); }}inline int que2(int p){ int re=-INF; for(;p<=maxVal;p+=lowbit(p)) if(mark[p]==cl) re=max(re,c[p]); return re;}int ans[N];void sol(int l,int r){
//printf("sol %d %d\n",l,r); int mid=(l+r)>>1; cl++; for(int i=l;i<=r;i++){ if(!a[i].op&&a[i].id<=mid) upd(a[i].y,a[i].x+a[i].y); else if(a[i].op&&a[i].id>mid) ans[a[i].qid]=min(ans[a[i].qid],a[i].x+a[i].y-que(a[i].y)); } cl++; for(int i=l;i<=r;i++){ if(!a[i].op&&a[i].id<=mid) upd2(a[i].y,a[i].x-a[i].y); else if(a[i].op&&a[i].id>mid) ans[a[i].qid]=min(ans[a[i].qid],a[i].x-a[i].y-que2(a[i].y)); } cl++; for(int i=r;i>=l;i--){ if(!a[i].op&&a[i].id<=mid) upd(a[i].y,a[i].y-a[i].x); else if(a[i].op&&a[i].id>mid) ans[a[i].qid]=min(ans[a[i].qid],a[i].y-a[i].x-que(a[i].y)); } cl++; for(int i=r;i>=l;i--){ if(!a[i].op&&a[i].id<=mid) upd2(a[i].y,-a[i].y-a[i].x); else if(a[i].op&&a[i].id>mid) ans[a[i].qid]=min(ans[a[i].qid],-a[i].y-a[i].x-que2(a[i].y)); } //for(int i=1;i<=qid;i++) printf("%d ",ans[i]);puts("end");}void CDQ(int l,int r){
//printf("CDQ %d %d\n",l,r); if(l==r) return; int mid=(l+r)>>1; CDQ(l,mid);CDQ(mid+1,r); int i=l,j=mid+1,p=l; while(i<=mid||j<=r){ if(j>r||(i<=mid&&a[i].x<=a[j].x)) t[p++]=a[i++]; else t[p++]=a[j++]; } for(int i=l;i<=r;i++) a[i]=t[i]; sol(l,r);}int main(){ freopen("in","r",stdin); //freopen("out","w",stdout); n=read();m=read(); for(int i=1;i<=n;i++){ a[i].x=read()+1,a[i].y=read()+1,a[i].id=i; maxVal=max(maxVal,max(a[i].x,a[i].y)); } for(int i=1;i<=m;i++){ a[++n].op=read()-1,a[n].x=read()+1,a[n].y=read()+1,a[n].id=n; if(a[n].op) a[n].qid=++qid; maxVal=max(maxVal,max(a[n].x,a[n].y)); } //for(int i=n-m+1;i<=n;i++) printf("check %d %d %d %d\n",i,a[i].x,a[i].y,a[i].qid); //printf("n %d %d %d\n",n,qid,maxVal); for(int i=1;i<=qid;i++) ans[i]=INF; CDQ(1,n); for(int i=1;i<=qid;i++) put(ans[i]);}

 

转载地址:http://mpghl.baihongyu.com/

你可能感兴趣的文章
Oracle表空间维护总结
查看>>
12C -- ORA-01017
查看>>
约瑟夫环问题
查看>>
Compile、Make和Build的区别(as make, build, clean, run)
查看>>
介绍三款串口监控工具:Device Monitoring Studio,portmon,Comspy
查看>>
Bulk Load-HBase数据导入最佳实践
查看>>
sqlServer的主键只能自增不能手动增加
查看>>
maven常用命令介绍
查看>>
【树莓派】树莓派上刷android系统
查看>>
J2EE之Servlet初见
查看>>
elasticsearch best_fields most_fields cross_fields从内在实现看区别——本质就是前两者是以field为中心,后者是词条为中心...
查看>>
JPA(一):简介
查看>>
git 的安装和使用
查看>>
(转) OpenCV学习笔记大集锦 与 图像视觉博客资源2之MIT斯坦福CMU
查看>>
Controller 接口控制器详解
查看>>
【转】【MySQL】mysql 通过bin-log恢复数据方法详解
查看>>
linux上安装启动elasticsearch-5.5.1完整步骤
查看>>
Silverlight 4 MVVM开发方式(一)小黑端
查看>>
公告:CSDN博客频道新功能正式上线!
查看>>
Web服务的体系架构
查看>>