【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树
外层是借鉴了kd-tree的替罪羊里层是线段树,插入就是正常插入+拍扁重建,查询的时候,我们就像树状数组套线段树一样操作在替罪羊中找到的线段树根节点,但是对于在kd-tree查找过程中遇到的单点,我们并不能将其插入到额外的线段树中,因为你想我们的单点个数是n^1.5级别的,而我们还要乘上一个大到30的logn,就算时间受得了,空间也受不了,就算是回收也可能出事,所以我们就用数组来存单点,查询的时候顺便二分就好了。
(YY出了一种用链表回收的鬼畜做法....)
(话说我的空间好像是nlognlogn的.......额.....好像......我不管,我过了)(以后一定要先算内存的啊)
#include <cstdio>
#include <cstring>
#include <algorithm>
char xB[(<<)+],*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=;ch<''||ch>'';ch=gtc);
for(;ch>=''&&ch<='';x=(x<<)+(x<<)+ch-'',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=;
const int oo=;
const int Inf=0x3f3f3f3f;
const double alpha=0.72;
struct Point{
int x[],w;
}list[N];
int len,cmp;
inline bool comp(Point a,Point b){
return a.x[cmp]<b.x[cmp];
}
struct Segment_Tree{
Segment_Tree *ch[];
int size;
inline void* operator new (size_t);
}*k1[N*],*k2[N*],*C,*mempool,*null,*head;
int len1,len2;
int t1[*N],t2[*N],cnt1,cnt2;
inline void* Segment_Tree:: operator new (size_t){
if(C==mempool){
C=new Segment_Tree[(<<)+];
mempool=C+(<<)+;
}
return C++;
}
inline void Init_Segment_Tree(){
null=new Segment_Tree;
null->ch[]=null->ch[]=null;
null->size=;
}
inline void get(Segment_Tree *p){
p->ch[]=head,head=p;
}
inline Segment_Tree *New(){
Segment_Tree *ret;
if(head!=NULL)
ret=head,head=head->ch[];
else
ret=new Segment_Tree;
ret->ch[]=ret->ch[]=null;
ret->size=;
return ret;
}
inline void bang(Segment_Tree *p){
if(p==null)return;
bang(p->ch[]),bang(p->ch[]);
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[],l,mid,key);
else insert(p->ch[],mid+,r,key);
}
inline int query(int *x,int z,int y,int jud){
if(x[z]>jud)return z-;
int l=z,r=y,ret=y;
while(l<=r){
if(x[mid]<=jud)
ret=mid,l=mid+;
else
r=mid-;
}
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=,i,mid1=query(t1,a,b,mid),mid2=query(t2,c,d,mid);
for(i=;i<len1;++i)sum+=k1[i]->ch[]->size;
for(i=;i<len2;++i)sum-=k2[i]->ch[]->size;
sum+=b-mid1,sum-=d-mid2;
if(sum>=k){
for(i=;i<len1;++i)k1[i]=k1[i]->ch[];
for(i=;i<len2;++i)k2[i]=k2[i]->ch[];
return query(mid+,r,mid1+,b,mid2+,d,k);
}else{
for(i=;i<len1;++i)k1[i]=k1[i]->ch[];
for(i=;i<len2;++i)k2[i]=k2[i]->ch[];
return query(l,mid,a,mid1,c,mid2,k-sum);
}
}
struct ScapeGoat_Tree{
ScapeGoat_Tree *ch[];
Segment_Tree *root;
int max[],min[],size;
Point poi;
inline void update(int *x){
max[]=diymax(max[],x[]);
max[]=diymax(max[],x[]);
min[]=diymin(min[],x[]);
min[]=diymin(min[],x[]);
}
inline void pushup(){
max[]=diymax(max[],ch[]->max[]);
max[]=diymax(max[],ch[]->max[]);
min[]=diymin(min[],ch[]->min[]);
min[]=diymin(min[],ch[]->min[]);
max[]=diymax(max[],ch[]->max[]);
max[]=diymax(max[],ch[]->max[]);
min[]=diymin(min[],ch[]->min[]);
min[]=diymin(min[],ch[]->min[]);
size=ch[]->size+ch[]->size+;
}
inline bool judge(int *x){
return x[]>=poi.x[]&&x[]>=poi.x[];
}
inline bool judge_max(int *x){
return x[]>=max[]&&x[]>=max[];
}
inline bool judge_min(int *x){
return x[]>=min[]&&x[]>=min[];
}
inline bool isbad(){
return size*alpha+<ch[]->size||size*alpha+<ch[]->size;
}
}*root,*Null,node[N],*stack[N];
int sz,top;
inline void New(ScapeGoat_Tree *p,Point poi){
p->size=,p->poi=poi;
p->root=null;
p->max[]=p->min[]=poi.x[];
p->max[]=p->min[]=poi.x[];
p->ch[]=p->ch[]=Null;
insert(p->root,,oo,poi.w);
}
inline void Init_ScapeGoat_Tree(){
Null=newnode;
Null->ch[]=Null->ch[]=Null;
Null->root=null;
Null->max[]=Null->max[]=-Inf;
Null->min[]=Null->min[]=Inf;
Null->size=;
root=Null;
}
inline void travel(ScapeGoat_Tree *p){
if(p==Null)return;
travel(p->ch[]),travel(p->ch[]);
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+,comp);
New(p=renode,list[mid]);
for(int i=l;i<=r;++i)
if(i!=mid)insert(p->root,,oo,list[i].w);
build(p->ch[],l,mid-,id^);
build(p->ch[],mid+,r,id^);
p->pushup();
}
inline void rebuild(ScapeGoat_Tree *&p,int id){
len=,top=,travel(p),build(p,,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,,oo,poi.w),++p->size;
insert(p->ch[poi.x[id]>p->poi.x[id]],poi,id^,ret1,ret2);
if(p->isbad())ret1=p,ret2=id;
}
inline void Insert(Point poi){
ScapeGoat_Tree *p=Null;int id=;
insert(root,poi,,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[],x,k,t,y,cc),dfs(p->ch[],x,k,t,y,cc);
}
int main(){
Init_Segment_Tree();
Init_ScapeGoat_Tree();
int T,x,y,a,b,k,f[],ans=,opt,cnt,i,clc=;
Point temp;
read(x),read(T);
while(T--){
read(opt);
if(opt==){
read(x),read(y),read(a);
x^=ans,y^=ans,a^=ans;
temp.x[]=x,temp.x[]=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=;
f[]=x-,f[]=y-,dfs(root,f,k1,len1,t1,cnt1);
f[]=a,f[]=y-,dfs(root,f,k2,len2,t2,cnt2);
f[]=x-,f[]=b,dfs(root,f,k2,len2,t2,cnt2);
f[]=a,f[]=b,dfs(root,f,k1,len1,t1,cnt1);
cnt=cnt1-cnt2;
for(i=;i<len1;++i)cnt+=k1[i]->size;
for(i=;i<len2;++i)cnt-=k2[i]->size;
if(cnt<k)
puts("NAIVE!ORZzyz."),ans=;
else{
std::sort(t1+,t1+cnt1+);
std::sort(t2+,t2+cnt2+);
ans=query(,oo,,cnt1,,cnt2,k);
printf("%d\n",ans);
}
}
}
return ;
}
【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树的更多相关文章
- BZOJ 4605 崂山白花蛇草水(权值线段树+KD树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4605 [题目大意] 操作 1 x y k 表示在点(x,y)上放置k个物品, 操作 2 ...
- bzoj 4605: 崂山白花蛇草水
Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实 力,他轻松地进了山东省省队,现在便是他履行诺言的时 ...
- [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】
题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...
- dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448
4448: [Scoi2015]情报传递 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 588 Solved: 308[Submit][Status ...
- [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)
[BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...
- bzoj 3110 [Zjoi2013]K大数查询——线段树套线段树(标记永久化)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3110 第一道线段树套线段树! 第一道标记永久化! 为什么为什么写了两个半小时啊…… 本想线段 ...
- ZJOI 2017 树状数组(线段树套线段树)
题意 http://uoj.ac/problem/291 思路 不难发现,九条カレン醬所写的树状数组,在查询区间 \([1,r]\) 的时候,其实在查询后缀 \([r,n]\) :在查询 \([l,r ...
- BZOJ4317Atm的树&BZOJ2051A Problem For Fun&BZOJ2117[2010国家集训队]Crash的旅游计划——二分答案+动态点分治(点分树套线段树/点分树+vector)
题目描述 Atm有一段时间在虐qtree的题目,于是,他满脑子都是tree,tree,tree…… 于是,一天晚上他梦到自己被关在了一个有根树中,每条路径都有边权,一个神秘的声音告诉他,每个点到其他的 ...
- hdu-4819-线段树套线段树
http://acm.hdu.edu.cn/showproblem.php?pid=4819 给出一个N*N的矩阵,每次询问一个m*m的子矩阵里的floor((maxv+minv)/2)并把中间的元素 ...
- 【vijos】1750 建房子(线段树套线段树+前缀和)
https://vijos.org/p/1750 是不是我想复杂了.... 自己yy了个二维线段树,然后愉快的敲打. 但是wa了两法.......sad 原因是在处理第二维的更新出现了个小问题,sad ...
随机推荐
- Leecode刷题之旅-C语言/python-100相同的树
/* * @lc app=leetcode.cn id=100 lang=c * * [100] 相同的树 * * https://leetcode-cn.com/problems/same-tree ...
- C# FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址。"的错误
FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址."的错误 解决方法是在原代码上增加这句话 reqFTP.UsePassive = f ...
- BZOJ:2038: [2009国家集训队]小Z的袜子(hose)(莫队算法模板)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 解题心得: 第一次接触莫队算法,很神奇,很巧妙.莫队算法主要就是用来解决多次询问时 ...
- Servlet生命周期与线程安全
上一篇介绍了Servlet初始化,以及如何处理HTTP请求,实际上在这两个过程中,都伴随着Servlet的生命周期,都是Servlet生命周期的一部分.同时,由于Tomcat容器默认是采用单实例多线程 ...
- python2.7练习小例子(十一)
11):题目:判断101-200之间有多少个素数,并输出所有素数. 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数. ...
- Nginx一直报504超时,配置相关参数好了
相关参数:large_client_header_buffers 4 16k;client_max_body_size 30m;client_body_buffer_size 128k;proxy_c ...
- 网站的robots.txt文件
什么是robots.txt? robots.txt是一个纯文本文件,是爬虫抓取网站的时候要查看的第一个文件,一般位于网站的根目录下.robots.txt文件定义了爬虫在爬取该网站时存在的限制,哪些部分 ...
- React实现最完整的百度搜索框
import React,{Component} from 'react' import ReactDOM,{render} from 'react-dom' import 'bootstrap/di ...
- SGU刷题之路,开始了
0. 关于SGU的简介 SGU的网址是:acm.sgu.ru 向不了解的同学介绍一下SGU这个题库: 1. 题目难度很高,题目大多很经典. 2. 其数据范围很小,时间和空间要求也都很小,同时很精确.甚 ...
- 常见bug解析-移动端
手机测试常见bug解析 1.测试时遇到“手机无响应”? 有以下几个原因: a.手机内存不足 b.android进程之间死锁引起的(就是两个进程之间) c.手机的CPU运行高引起的 可以查看手机的崩溃日 ...