Description

神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水。凭借着神犇Aleph的实
力,他轻松地进了山东省省队,现在便是他履行诺言的时候了。蒟蒻Bob特地为他准备了999,999,999,999,999,999
瓶崂山白花蛇草水,想要灌神犇Aleph。神犇Aleph求(跪着的)蒟蒻Bob不要灌他,由于神犇Aleph是神犇,蒟蒻Bo
b最终答应了他的请求,但蒟蒻Bob决定将计就计,也让神犇Aleph回答一些问题。具体说来,蒟蒻Bob会在一个宽敞
的广场上放置一些崂山白花蛇草水(可视为二维平面上的一些整点),然后询问神犇Aleph在矩形区域(x1, y1), (
x2, y2)(x1≤x2且y1≤y2,包括边界)中,崂山白花蛇草水瓶数第k多的是多少。为了避免麻烦,蒟蒻Bob不会在同
一个位置放置两次或两次以上的崂山白花蛇草水,但蒟蒻Bob想为难一下神犇Aleph,希望他能在每次询问时立刻回
答出答案。神犇Aleph不屑于做这种问题,所以把这个问题交给了你。

Input

输入的第一行为两个正整数N, Q,表示横纵坐标的范围和蒟蒻Bob的操作次数(包括放置次数和询问次数)。
接下来Q行,每行代表蒟蒻Bob的一个操作,操作格式如下:
首先第一个数字type,表示操作种类。type=1表示放置,type=2表示询问。
若type=1,接下来会有三个正整数x, y, v,表示在坐标整点(x, y)放置v瓶崂山白花蛇草水。(1≤x, y≤N, 1≤v≤10^9)
若type=2,接下来会有五个正整数x1, y1, x2, y2, k,表示询问矩形区域(x1, y1), (x2, y2)中,崂山白花蛇草水瓶数第k多的是多少。
(1≤x1≤x2≤N,1≤y1≤y2≤N,1≤k≤Q)
为了体现程序的在线性,你需要将每次读入的数据(除了type值)都异或lastans,其中lastans表示上次询问的答
案。如果上次询问的答案为"NAIVE!ORZzyz."(见样例输出),则将lastans置为0。初始时的lastans为0。
初始时平面上不存在崂山白花蛇草水。
本题共有12组测试数据。对于所有的数据,N≤500,000。
Q的范围见下表:
测试点1-2     Q=1,000
测试点3-7     Q=50,000
测试点8-12     Q=100,000
 
 

Output

对于每个询问(type=2的操作),回答崂山白花蛇草水瓶数第k多的是多少。若不存在第k多的瓶数,
请输出"NAIVE!ORZzyz."(输出不含双引号)。
 
外层一个权值线段树来二分权值,线段树中每个节点开一颗 KDtree 来数点,这么边数点边二分即可.

Code:

// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) //,freopen(s".out","w",stdout)
struct Data
{
int ch[2],w,minv[2],maxv[2],p[2],siz,sum;
}node[20000000], arr[20000000];
namespace KDtree
{
#define maxn 20000000
#define Min(a,b) (a = a>b?b:a)
#define Max(a,b) (a = b>a?b:a)
int d,c_arr;
std::queue<int>Q;
void Init()
{
for(int i=1;i<maxn;++i) Q.push(i);
}
int newnode(){ int q = Q.front(); Q.pop(); return q; }
bool cmp(Data i,Data j)
{
return i.p[d]==j.p[d]?i.p[d^1]<j.p[d^1]:i.p[d]<j.p[d];
}
bool isout(int k,int x1,int y1,int x2,int y2)
{
if(node[k].maxv[0]<x1||node[k].minv[0]>x2||node[k].maxv[1]<y1||node[k].minv[1]>y2) return 1;
return 0;
}
bool isin(int k,int x1,int y1,int x2,int y2)
{
if(node[k].maxv[0]<=x2 && node[k].minv[0]>=x1&&node[k].maxv[1]<=y2&&node[k].minv[1]>=y1) return 1;
return 0;
}
void pushup(int x,Data p)
{
node[x].sum+=p.sum;
node[x].siz+=p.siz;
Min(node[x].minv[0],p.minv[0]);
Min(node[x].minv[1],p.minv[1]);
Max(node[x].maxv[0],p.maxv[0]);
Max(node[x].maxv[1],p.maxv[1]);
}
int query(int x,int x1,int y1,int x2,int y2)
{
if(!x||isout(x,x1,y1,x2,y2)) return 0;
if(isin(x,x1,y1,x2,y2))
{
return node[x].sum;
}
int ans=0;
if(node[x].p[0]>=x1&&node[x].p[0]<=x2&&node[x].p[1]>=y1&&node[x].p[1]<=y2) ans=1;
ans += query(node[x].ch[0],x1,y1,x2,y2)+query(node[x].ch[1],x1,y1,x2,y2);
return ans;
}
void dfs(int &o)
{
if(!o) return;
dfs(node[o].ch[0]);
arr[++c_arr] = node[o];
arr[c_arr].sum=arr[c_arr].w=1;
arr[c_arr].maxv[0]=arr[c_arr].minv[0]=arr[c_arr].p[0];
arr[c_arr].maxv[1]=arr[c_arr].minv[1]=arr[c_arr].p[1];
arr[c_arr].siz=1;
Q.push(o);
dfs(node[o].ch[1]);
o=0;
}
void rebuild(int &x,int l,int r,int o)
{
int mid=(l+r)>>1;
d=o,std::nth_element(arr+l,arr+mid,arr+1+r,cmp);
x=newnode();
node[x]=arr[mid];
node[x].minv[0]=node[x].maxv[0]=node[x].p[0];
node[x].minv[1]=node[x].maxv[1]=node[x].p[1];
node[x].sum=node[x].w=1;
node[x].ch[0]=node[x].ch[1]=0;
node[x].siz=1;
if(l<mid) rebuild(node[x].ch[0],l,mid-1,o^1), pushup(x, node[node[x].ch[0]]);
if(r>mid) rebuild(node[x].ch[1],mid+1,r,o^1), pushup(x, node[node[x].ch[1]]);
}
void Reconstruct(int &u)
{
c_arr=0;
dfs(u);
rebuild(u,1,c_arr,d=0);
}
bool check(int son,int x)
{
if(son*10>x*9) return true;
return false;
}
void insert(int &x,Data a,int de,int tag)
{
if(!x)
{
x=newnode();
node[x].p[0]=node[x].maxv[0]=node[x].minv[0]=a.p[0];
node[x].p[1]=node[x].maxv[1]=node[x].minv[1]=a.p[1];
node[x].sum=node[x].w=1;
node[x].siz=1,node[x].ch[0]=node[x].ch[1]=0;
return;
}
d = de;
int is=0;
if(cmp(a,node[x]) == 1)
{
is = check(node[node[x].ch[0]].siz+1,node[x].siz+1);
insert(node[x].ch[0],a,de^1,is||tag);
pushup(x,a);
}
//a is bigger (rson)
else
{
is = check(node[node[x].ch[1]].siz+1,node[x].siz+1);
insert(node[x].ch[1],a,de^1,is||tag);
pushup(x,a);
}
if(tag && is) Reconstruct(x);
}
};
#define y1 opopopop
int lson[2000000],rson[2000000],rt[2000000];
int x1,y1,x2,y2, tot=0,root=0;
void modify(int &x,int l,int r,int k,Data i)
{
if(!x) x = ++tot;
KDtree::insert(rt[x],i,0,0);
if(l==r) return;
int mid = (l+r)>>1;
if(k <= mid) modify(lson[x],l,mid,k,i);
else modify(rson[x],mid+1,r,k,i);
}
int query(int x,int l,int r,int kth)
{
if(l==r) return l;
int u = KDtree::query(rt[rson[x]],x1,y1,x2,y2);
int mid = (l + r) >> 1;
if(u < kth)
return query(lson[x],l,mid,kth-u);
else
return query(rson[x],mid+1,r,kth);
}
int Query(int kth)
{
return query(root,0,1000000000,kth);
}
int n,q,lastans=0;
int main()
{
// setIO("input");
KDtree::Init();
scanf("%d%d",&n,&q);
for(int cc=1;cc<=q;++cc)
{
int opt,a,b,c,d;
scanf("%d",&opt);
if(opt==1)
{
scanf("%d%d%d",&a,&b,&c);
a^=lastans,b^=lastans,c^=lastans;
Data f;
f.p[0]=f.maxv[0]=f.minv[0]=a;
f.p[1]=f.maxv[1]=f.minv[1]=b;
f.ch[0]=f.ch[1]=0;
f.siz=1;
f.sum=f.w=1;
modify(root,0,1000000000,c,f);
}
if(opt==2)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&a);
x1^=lastans,y1^=lastans,x2^=lastans,y2^=lastans,a^=lastans;
lastans = Query(a);
if(lastans==0)
printf("NAIVE!ORZzyz.\n");
else
printf("%d\n",lastans);
}
}
return 0;
}

  

崂山白花蛇草水 权值线段树套KDtree的更多相关文章

  1. 【bzoj4605】崂山白花蛇草水 权值线段树套KD-tree

    题目描述 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了山东省省队,现在便是他履行诺言的时候了.蒟蒻Bob ...

  2. bzoj4605: 崂山白花蛇草水 权值线段树套KDtree

    bzoj4605: 崂山白花蛇草水 链接 bzoj loj 思路 强制在线,那就权值线段树套KDtree好了,没啥好讲的. KDtree要加平衡因子来重构.另外,那水真难喝. 错误 树套树一边写过了, ...

  3. 【BZOJ4605】崂山白花蛇草水 权值线段树+kd-tree

    [BZOJ4605]崂山白花蛇草水 Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了 ...

  4. 洛谷P4848 崂山白花蛇草水 权值线段树+KDtree

    题目描述 神犇 \(Aleph\) 在 \(SDOI\ Round2\) 前立了一个 \(flag\):如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇 \(Aleph\) 的实力,他轻松地进了山 ...

  5. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  6. [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)

    [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...

  7. BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

    题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...

  8. BZOJ3110[Zjoi2013]K大数查询——权值线段树套线段树

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...

  9. 【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

随机推荐

  1. [ javascript ] getElementsByClassName与className和getAttribute!

    对于javascript中的getElementsByClassName 在IE 6/7/8 不支持问题. 那么须要模拟出getElementsByClassName  须要採用className属性 ...

  2. hibernate使用c3p0数据源

    在配置好hibernate连接数据库环境的前提下,我们进行例如以下操作就能够搭建好hibernate中使用c3p0数据源的环境了. 1). 导入 jar 包: hibernate-release-4. ...

  3. HDU 5200 脑洞题 离线

    线段树,TLE,各种.唉....我真是笨死了.... 我用的线段树是记录左右区间最长连续棵数的...反正TLE #include <iostream> #include <cstdi ...

  4. leetcode中,代码怎样调试,创造本地执行环境

    初次接触leetcode,是我在一个招聘站点上看的,这个OJ真有那么厉害吗? 这几天在这个OJ上做了几道题,发现他的几个特点,1.题目不难(相对于ACM来说,我被ACM虐到至今无力),评判没那么苛刻, ...

  5. vbs setkeys 特殊符号

    set keys={~}!^@^#^${%%}{^&^}{^^}{*}{(}{)}{_}{-}{=}{+}.;:'"

  6. hdu1542 线段树+扫描线+离散化

    仅仅想说题目给的欲实际不服     还是这类型的水题吧   建议看之前我写的那个 #include<stdio.h> #include<string.h> #include&l ...

  7. hdu1325 Is It A Tree?(二叉树的推断)

    Is It A Tree? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  8. hook 鼠标键盘消息实例分析

    1.木马控制及通信方法包含:双管道,port重用.反弹技术.Hook技术,今天重点引用介绍一下hook的使用方法,hook信息后能够将结果发送到hacker邮箱等.实现攻击的目的. 转自:http:/ ...

  9. BZOJ 1787: [Ahoi2008]Meet 紧急集合 LCA

    1787: [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 ...

  10. 【c语言】字符串替换空格:请实现一个函数,把字符串中的每一个空格替换成“%20”

    // 字符串替换空格:请实现一个函数,把字符串中的每一个空格替换成"%20". // 比如输入"we are happy.",则输出"we%20are ...