bzoj4605: 崂山白花蛇草水
题意
Q(<=100000)次操作,支持:
在二维平面上插入一个坐标(x,y)(x,y<=500000),点权为v(<=1e9)的点;
查询矩形区域内第K大点权。
强制在线。
题解
今天neither问我在做什么题,我说是一个kdt模板题
双log的话空间似乎会炸?
所以就线段树套KDT了。
对于插入操作,我们把一个点插到权值线段树上对应的log棵KDT里。因为带插入KDT需要替罪羊式重构来保证平衡,所以单次复杂度log^2。
对于查询操作…直接在线段树上一路查下去就可以,单次复杂度是根号*log的。
这个整体复杂度是 O(nlog2n(log2n+n−−√)) O ( n log 2 n ( log 2 n + n ) ) 。
怎么看都会炸,但是可以过(笑
代码
为什么我 跑得 这 么 慢
↑然后发现自己每篇题解里几乎都出现了这句话。。
我自带巨大常数 QAQ
#include<bits/stdc++.h>
#define N 100005
#define V 3000005
using namespace std;
char ch;
int lans;
inline void rd(int &x)
{
x=0;
while((ch=getchar()-'0')<0|ch>9);
for(;ch>-1&ch<10;x=(x<<3)+
(x<<1)+ch,ch=getchar()-'0');
x^=lans;
}
int q,l,r,mid,i,k,rt[V],C[2][V],Cnt=1,
c[2][V],xx[2][V],mx[2][V],mn[2][V],sz[V],cnt,
op,p,X[2],x2,y2,st[N],nxt[N],t;
bool dir[V];
void Del(int &x)
{
if(!x)return;
st[++t]=x;
Del(c[0][x]),Del(c[1][x]),x=0;
}
bool cmp(int x,int y)
{return xx[t][x]<xx[t][y];}
int reb(int L,int R,bool mode)
{
int Mid=L+R>>1,ret;
t=(mode^=1);
nth_element(st+L,st+Mid,st+R+1,cmp);
dir[ret=st[Mid]]=mode,sz[ret]=R-L+1;
for(int j=0;j<2;j++)
mn[j][ret]=mx[j][ret]=xx[j][ret];
if(L<Mid)
c[0][ret]=reb(L,Mid-1,mode);
if(Mid<R)
c[1][ret]=reb(Mid+1,R,mode);
for(int m=0;m<2;m++)
for(int j=0;j<2;j++)
if(c[m][ret])
mn[j][ret]=mn[j][mn[j][ret]<mn[j][c[m][ret]]?ret:c[m][ret]],
mx[j][ret]=mx[j][mx[j][ret]>mx[j][c[m][ret]]?ret:c[m][ret]];
return ret;
}
int qry(int x)
{
if(!x)return 0;
if(X[0]<=mn[0][x]&&X[1]<=mn[1][x]&&mx[0][x]<=x2&&mx[1][x]<=y2)
return sz[x];
return (X[0]<=xx[0][x]&&X[1]<=xx[1][x]&&x2>=xx[0][x]&&y2>=xx[1][x])+
(X[dir[x]]>mx[dir[x]][c[0][x]]?0:qry(c[0][x]))+
((dir[x]?y2:x2)<mn[dir[x]][c[1][x]]?0:qry(c[1][x]));
}
int main()
{
rd(q),rd(q);
while(q--)
{
rd(op),op^=lans;
rd(X[0]),rd(X[1]);
l=1,r=1e9;
if(op<2)
{
rd(k),p=1;
for(;;)
{
sz[++cnt]=1;
for(int j=0;j<2;j++)
mn[j][cnt]=mx[j][cnt]=xx[j][cnt]=X[j];
if(i=rt[p])
{
y2=0;
qwq:
sz[i]++,x2=X[dir[i]]>xx[dir[i]][i];
for(int j=0;j<2;j++)
mn[j][i]=mn[j][i]<X[j]?mn[j][i]:X[j],
mx[j][i]=mx[j][i]>X[j]?mx[j][i]:X[j];
if(!c[x2][i])c[x2][i]=cnt,dir[cnt]=dir[i]^1;
else if(c[x2][i][sz]+1<<2>sz[i]*3)
st[t=1]=cnt,Del(x2=i),
y2?c[c[1][y2]==i][y2]=reb(1,t,dir[y2]):(rt[p]=reb(1,t,1));
else
{
i=c[x2][y2=i];
goto qwq;
}
}
else rt[p]=cnt;
if(l==r)break;
(x2=(mid=l+r>>1)<k)?l=mid+1:r=mid;
p=C[x2][p]=C[x2][p]?C[x2][p]:++Cnt;
}
}
else
{
rd(x2),rd(y2),rd(k);
if((i=qry(rt[p=1]))<k)
lans=0,puts("NAIVE!ORZzyz.");
else
{
while(l<r)
{
mid=l+r>>1;
(i=qry(rt[C[1][p]]))<k?
r=mid,k-=i,p=C[0][p]:(l=mid+1,p=C[1][p]);
}
printf("%d\n",lans=l);
}
}
}
}