博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树
阅读量:5083 次
发布时间:2019-06-13

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

外层是借鉴了kd-tree的替罪羊里层是线段树,插入就是正常插入+拍扁重建,查询的时候,我们就像树状数组套线段树一样操作在替罪羊中找到的线段树根节点,但是对于在kd-tree查找过程中遇到的单点,我们并不能将其插入到额外的线段树中,因为你想我们的单点个数是n^1.5级别的,而我们还要乘上一个大到30的logn,就算时间受得了,空间也受不了,就算是回收也可能出事,所以我们就用数组来存单点,查询的时候顺便二分就好了。

(YY出了一种用链表回收的鬼畜做法....)

(话说我的空间好像是nlognlogn的.......额.....好像......我不管,我过了)(以后一定要先算内存的啊)

#include 
#include
#include
char xB[(1<<15)+10],*xS,*xT;#define gtc (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++)inline void read(int &x){ register char ch=gtc; for(x=0;ch<'0'||ch>'9';ch=gtc); for(;ch>='0'&&ch<='9';x=(x<<1)+(x<<3)+ch-'0',ch=gtc);}#define mid ((l+r)>>1)#define newnode (node+(sz++))#define renode (stack[top--])#define diymax(a,b) ((a)>(b)?(a):(b))#define diymin(a,b) ((a)<(b)?(a):(b))const int N=100010;const int oo=1000000000;const int Inf=0x3f3f3f3f;const double alpha=0.72;struct Point{ int x[2],w;}list[N];int len,cmp;inline bool comp(Point a,Point b){ return a.x[cmp]
ch[0]=null->ch[1]=null; null->size=0;}inline void get(Segment_Tree *p){ p->ch[0]=head,head=p;}inline Segment_Tree *New(){ Segment_Tree *ret; if(head!=NULL) ret=head,head=head->ch[0]; else ret=new Segment_Tree; ret->ch[0]=ret->ch[1]=null; ret->size=0; return ret;}inline void bang(Segment_Tree *p){ if(p==null)return; bang(p->ch[0]),bang(p->ch[1]); get(p);}inline void insert(Segment_Tree *&p,int l,int r,int key){ if(p==null)p=New(); ++p->size; if(l==r)return; if(key<=mid)insert(p->ch[0],l,mid,key); else insert(p->ch[1],mid+1,r,key);}inline int query(int *x,int z,int y,int jud){ if(x[z]>jud)return z-1; int l=z,r=y,ret=y; while(l<=r){ if(x[mid]<=jud) ret=mid,l=mid+1; else r=mid-1; } return ret;}inline int query(int l,int r,int a,int b,int c,int d,int k){ if(l==r)return l; int sum=0,i,mid1=query(t1,a,b,mid),mid2=query(t2,c,d,mid); for(i=0;i
ch[1]->size; for(i=0;i
ch[1]->size; sum+=b-mid1,sum-=d-mid2; if(sum>=k){ for(i=0;i
ch[1]; for(i=0;i
ch[1]; return query(mid+1,r,mid1+1,b,mid2+1,d,k); }else{ for(i=0;i
ch[0]; for(i=0;i
ch[0]; return query(l,mid,a,mid1,c,mid2,k-sum); }}struct ScapeGoat_Tree{ ScapeGoat_Tree *ch[2]; Segment_Tree *root; int max[2],min[2],size; Point poi; inline void update(int *x){ max[0]=diymax(max[0],x[0]); max[1]=diymax(max[1],x[1]); min[0]=diymin(min[0],x[0]); min[1]=diymin(min[1],x[1]); } inline void pushup(){ max[0]=diymax(max[0],ch[0]->max[0]); max[1]=diymax(max[1],ch[0]->max[1]); min[0]=diymin(min[0],ch[0]->min[0]); min[1]=diymin(min[1],ch[0]->min[1]); max[0]=diymax(max[0],ch[1]->max[0]); max[1]=diymax(max[1],ch[1]->max[1]); min[0]=diymin(min[0],ch[1]->min[0]); min[1]=diymin(min[1],ch[1]->min[1]); size=ch[0]->size+ch[1]->size+1; } inline bool judge(int *x){ return x[0]>=poi.x[0]&&x[1]>=poi.x[1]; } inline bool judge_max(int *x){ return x[0]>=max[0]&&x[1]>=max[1]; } inline bool judge_min(int *x){ return x[0]>=min[0]&&x[1]>=min[1]; } inline bool isbad(){ return size*alpha+10
size||size*alpha+10
size; }}*root,*Null,node[N],*stack[N];int sz,top;inline void New(ScapeGoat_Tree *p,Point poi){ p->size=1,p->poi=poi; p->root=null; p->max[0]=p->min[0]=poi.x[0]; p->max[1]=p->min[1]=poi.x[1]; p->ch[0]=p->ch[1]=Null; insert(p->root,1,oo,poi.w);}inline void Init_ScapeGoat_Tree(){ Null=newnode; Null->ch[0]=Null->ch[1]=Null; Null->root=null; Null->max[0]=Null->max[1]=-Inf; Null->min[0]=Null->min[1]=Inf; Null->size=0; root=Null;}inline void travel(ScapeGoat_Tree *p){ if(p==Null)return; travel(p->ch[0]),travel(p->ch[1]); list[++len]=p->poi,stack[++top]=p,bang(p->root);}inline void build(ScapeGoat_Tree *&p,int l,int r,int id){ if(l>r)return void(p=Null); cmp=id,std::nth_element(list+l,list+mid,list+r+1,comp); New(p=renode,list[mid]); for(int i=l;i<=r;++i) if(i!=mid)insert(p->root,1,oo,list[i].w); build(p->ch[0],l,mid-1,id^1); build(p->ch[1],mid+1,r,id^1); p->pushup();}inline void rebuild(ScapeGoat_Tree *&p,int id){ len=0,top=0,travel(p),build(p,1,len,id);} inline void insert(ScapeGoat_Tree *&p,Point poi,int id,ScapeGoat_Tree *&ret1,int &ret2){ if(p==Null)return void(New(p=newnode,poi)); p->update(poi.x),insert(p->root,1,oo,poi.w),++p->size; insert(p->ch[poi.x[id]>p->poi.x[id]],poi,id^1,ret1,ret2); if(p->isbad())ret1=p,ret2=id;}inline void Insert(Point poi){ ScapeGoat_Tree *p=Null;int id=0; insert(root,poi,0,p,id); if(p!=Null)rebuild(p,id);}inline void dfs(ScapeGoat_Tree *p,int *x,Segment_Tree **k,int &t,int *y,int &cc){ if(p==Null)return; if(p->judge_max(x))return void(k[t++]=p->root); if(!p->judge_min(x))return; if(p->judge(x))y[++cc]=p->poi.w; dfs(p->ch[0],x,k,t,y,cc),dfs(p->ch[1],x,k,t,y,cc);}int main(){ Init_Segment_Tree(); Init_ScapeGoat_Tree(); int T,x,y,a,b,k,f[2],ans=0,opt,cnt,i,clc=0; Point temp; read(x),read(T); while(T--){ read(opt); if(opt==1){ read(x),read(y),read(a); x^=ans,y^=ans,a^=ans; temp.x[0]=x,temp.x[1]=y,temp.w=a; Insert(temp); }else{ read(x),read(y),read(a),read(b),read(k); x^=ans,y^=ans,a^=ans,b^=ans,k^=ans; cnt=len1=len2=cnt1=cnt2=0; f[0]=x-1,f[1]=y-1,dfs(root,f,k1,len1,t1,cnt1); f[0]=a,f[1]=y-1,dfs(root,f,k2,len2,t2,cnt2); f[0]=x-1,f[1]=b,dfs(root,f,k2,len2,t2,cnt2); f[0]=a,f[1]=b,dfs(root,f,k1,len1,t1,cnt1); cnt=cnt1-cnt2; for(i=0;i
size; for(i=0;i
size; if(cnt
View Code

 

转载于:https://www.cnblogs.com/TSHugh/p/8179089.html

你可能感兴趣的文章
Python内置函数(29)——help
查看>>
Android TextView加上阴影效果
查看>>
《梦断代码》读书笔记(三)
查看>>
AngularJS学习篇(一)
查看>>
关于Xshell无法连接centos6.4的问题
查看>>
spring security 11种过滤器介绍
查看>>
代码实现导航栏分割线
查看>>
大数据学习系列(8)-- WordCount+Block+Split+Shuffle+Map+Reduce技术详解
查看>>
Mysql性能调优
查看>>
ES6内置方法find 和 filter的区别在哪
查看>>
Android实现 ScrollView + ListView无滚动条滚动
查看>>
硬件笔记之Thinkpad T470P更换2K屏幕
查看>>
getElement的几中属性介绍
查看>>
HTML列表,表格与媒体元素
查看>>
设计器 和后台代码的转换 快捷键
查看>>
STL容器之vector
查看>>
数据中心虚拟化技术
查看>>
复习文件操作
查看>>
SQL Server 使用作业设置定时任务之一(转载)
查看>>
第二阶段冲刺-01
查看>>