版权声明:虽然是个蒟蒻但是转载还是要说一声的哟 https://blog.csdn.net/jpwang8/article/details/85081256
Description
Q次操作,要求资瓷
- 在(x,y)处放一个数字x
- 查询(x1,y1)到(x2,y2)矩形内第k大
Solution
非常裸的权值线段树套kd树,为了保证复杂度可以定期重构也可以平衡因子搞搞
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define max(x,y) (x>y?x:y)
#define min(x,y) (x<y?x:y)
const double alpha=0.6;
const int N=100005;
struct treeNode1 {
int l,r,p[2],mx[2],mn[2],sum,val;
} t1[N*40];
struct treeNode2 {
int l,r,root;
} t2[N*40];
int v[N],tot,cnt,wjp,rec,ff,typ;
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
void push_up(int x) {
t1[x].sum=t1[x].val;
t1[x].mn[0]=t1[x].mx[0]=t1[x].p[0];
t1[x].mn[1]=t1[x].mx[1]=t1[x].p[1];
if (t1[x].l) {
t1[x].mx[0]=max(t1[x].mx[0],t1[t1[x].l].mx[0]);
t1[x].mx[1]=max(t1[x].mx[1],t1[t1[x].l].mx[1]);
t1[x].mn[0]=min(t1[x].mn[0],t1[t1[x].l].mn[0]);
t1[x].mn[1]=min(t1[x].mn[1],t1[t1[x].l].mn[1]);
t1[x].sum+=t1[t1[x].l].sum;
}
if (t1[x].r) {
t1[x].mx[0]=max(t1[x].mx[0],t1[t1[x].r].mx[0]);
t1[x].mx[1]=max(t1[x].mx[1],t1[t1[x].r].mx[1]);
t1[x].mn[0]=min(t1[x].mn[0],t1[t1[x].r].mn[0]);
t1[x].mn[1]=min(t1[x].mn[1],t1[t1[x].r].mn[1]);
t1[x].sum+=t1[t1[x].r].sum;
}
}
bool cmp(int a,int b) {
return (t1[a].p[wjp]==t1[b].p[wjp])?(t1[a].p[!wjp]<t1[b].p[!wjp]):(t1[a].p[wjp]<t1[b].p[wjp]);
}
int build(int tl,int tr,int R) {
int mid=(tl+tr)>>1; wjp=R;
std:: nth_element(v+tl,v+mid,v+tr+1,cmp);
if (tl!=mid) t1[v[mid]].l=build(tl,mid-1,!R);
if (mid!=tr) t1[v[mid]].r=build(mid+1,tr,!R);
push_up(v[mid]); return v[mid];
}
void dfs(int now) {
v[++v[0]]=now;
if (t1[now].l) dfs(t1[now].l);
if (t1[now].r) dfs(t1[now].r);
t1[now].l=t1[now].r=0;
push_up(now);
}
void ins(int &now,int fa,int *p,int R) {
if (!now) { now=++tot;
t1[now].p[0]=t1[now].mx[0]=t1[now].mn[0]=p[0];
t1[now].p[1]=t1[now].mx[1]=t1[now].mn[1]=p[1];
t1[now].sum=t1[now].val=1;
return ;
}
if (p[R]<t1[now].p[R]) ins(t1[now].l,now,p,!R);
else ins(t1[now].r,now,p,!R);
push_up(now);
if (alpha*t1[now].sum<=t1[t1[now].l].sum) rec=now,ff=fa,typ=R;
if (alpha*t1[now].sum<=t1[t1[now].r].sum) rec=now,ff=fa,typ=R;
}
void modify(int &now,int tl,int tr,int x,int *p) {
if (!now) now=++cnt;
rec=ff=typ=0;
ins(t2[now].root,0,p,0);
if (rec) {
int d=(t1[ff].r==rec); v[0]=0;
dfs(rec); int tmp=build(1,v[0],typ);
if (ff) (d)?(t1[ff].r=tmp):(t1[ff].l=tmp);
else t2[now].root=tmp;
}
if (tl==tr) return ;
int mid=(tl+tr)>>1;
if (x<=mid) modify(t2[now].l,tl,mid,x,p);
else modify(t2[now].r,mid+1,tr,x,p);
}
bool check(int now,int x1,int y1,int x2,int y2) {
if (t1[now].mx[0]<x1||t1[now].mn[0]>x2) return false;
if (t1[now].mx[1]<y1||t1[now].mn[1]>y2) return false;
return true;
}
int ask(int now,int x1,int y1,int x2,int y2) {
if (!check(now,x1,y1,x2,y2)) return 0;
if (t1[now].mn[0]>=x1&&t1[now].mx[0]<=x2&&t1[now].mn[1]>=y1&&t1[now].mx[1]<=y2) return t1[now].sum;
int res=t1[now].val*(t1[now].p[0]>=x1&&t1[now].p[0]<=x2&&t1[now].p[1]>=y1&&t1[now].p[1]<=y2);
res+=ask(t1[now].l,x1,y1,x2,y2);
res+=ask(t1[now].r,x1,y1,x2,y2);
return res;
}
int query(int now,int tl,int tr,int k,int x1,int y1,int x2,int y2) {
if (tl==tr) return tl;
int mid=(tl+tr)>>1,w=ask(t2[t2[now].l].root,x1,y1,x2,y2);
if (w>=k) return query(t2[now].l,tl,mid,k,x1,y1,x2,y2);
return query(t2[now].r,mid+1,tr,k-w,x1,y1,x2,y2);
}
int main(void) {
int n=read(),T=read(),lxf=0;
for (int lastans=0;T--;) {
int opt=read();
if (opt==1) {
int x=read()^lastans,y=read()^lastans,v=read()^lastans;
int p[2]={x,y};
modify(lxf,1,1000000000,v,p);
} else {
int x1=read()^lastans,y1=read()^lastans,x2=read()^lastans,y2=read()^lastans;
int k=read()^lastans; int total=ask(t2[lxf].root,x1,y1,x2,y2);
if (total<k) puts("NAIVE!ORZzyz."),lastans=0;
else printf("%d\n", lastans=query(1,1,1000000000,total-k+1,x1,y1,x2,y2));
}
}
return 0;
}