考场上队友写这道题tle了,貌似是数组寻址花的时间过久加上splay常数过大
因此赛后re一遍,很久没写数据结构,调了老半天,最后9000+ms过了,虽然写得有点冗而且还是没改成指针,但是zkw线段树以及自顶向下splay的常数确实比较小
后来优化了一下删除,快了1000ms+
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
const int oo=1073741819;
using namespace std;
struct node{
int y,id,l,r,m_id;
}c[7000000];
struct point{
int x,y,w;
}b[200000];
struct rect{
int lx,rx,ly,ry,z;
}a[200000];
int n,m,ss,ans[200000],st,ls[200000],rs[200000],root[5000000];
int w[500000],u[500000],p[500000],m1,tot;
int max(int x,int y)
{
if (b[x].w<b[y].w) return x;
return y;
}
void updata(int x)
{
c[x].m_id=max(c[x].id,c[c[x].l].m_id);
c[x].m_id=max(c[x].m_id,c[c[x].r].m_id);
}
int right(int x,int y)
{
c[y].l=c[x].r,c[x].r=y,updata(y);
return x;
}
int left(int x,int y)
{
c[y].r=c[x].l,c[x].l=y,updata(y);
return x;
}
void rconnect(int x)
{
if (!rs[0]) {rs[rs[0]=1]=x;return ;}
c[rs[rs[0]]].l=x,rs[++rs[0]]=x;
}
void lconnect(int x)
{
if (!ls[0]) {ls[ls[0]=1]=x;return ;}
c[ls[ls[0]]].r=x,ls[++ls[0]]=x;
}
int cmp(int x,int y,int id)
{
if (y!=c[x].y) return (y<c[x].y) ? -1 : 1;
if (id!=c[x].id) return (id<c[x].id) ? -1 : 1;
return 0;
}
void splay(int &mid,int y,int id)
{
int pd,tmp;
ls[0]=rs[0]=0;
for (;mid && ((pd=cmp(mid,y,id))!=0);) {
if (pd<0) {
if (c[mid].l && cmp(c[mid].l,y,id)<0) mid=right(c[mid].l,mid);
rconnect(mid),tmp=c[mid].l,c[mid].l=0,mid=tmp;
}
else if (pd>0) {
if (c[mid].r && cmp(c[mid].r,y,id)>0) mid=left(c[mid].r,mid);
lconnect(mid),tmp=c[mid].r,c[mid].r=0,mid=tmp;
}
}
if (!mid) {
mid=++ss;
c[ss].y=y,c[ss].id=id;
}
if (c[mid].l) lconnect(c[mid].l);
if (c[mid].r) rconnect(c[mid].r);
for (int i=ls[0];i>=1;i--) updata(ls[i]);
for (int i=rs[0];i>=1;i--) updata(rs[i]);
if (ls[0]) c[mid].l=ls[1];
if (rs[0]) c[mid].r=rs[1];
updata(mid);
}
void origin()
{
for (m1=1;m1<=tot+2;m1<<=1) ;
ss=0;
}
void ins(int x,int y,int id)
{
for (x+=m1;x;x>>=1)
splay(root[x],y,id);
}
void del(int x,int y,int id)
{
for (x+=m1;x;x>>=1) {
// cout<<ss<<endl;
// cout<<ss<<endl;
// cout<<root[x]<<' '<<c[root[x]].y<<' '<<c[root[x]].id<<' '<<y<<' '<<id<<endl;
// c[root[x]].id=0;
splay(root[x],y,id);
if (!c[root[x]].r) root[x]=c[root[x]].l;
else if (!c[root[x]].l) root[x]=c[root[x]].r;
else {
int k=c[root[x]].r;
for (;c[k].l;k=c[k].l) ;
splay(c[root[x]].r,c[k].y,c[k].id);
c[c[root[x]].r].l=c[root[x]].l;
root[x]=c[root[x]].r;
updata(root[x]);
}
}
}
void doit(int x,int ly,int ry)
{
splay(root[x],ry,m+1);
splay(c[root[x]].l,ly,0);
int rt=root[x];
// cout<<rt<<' '<<c[rt].l<<' '<<c[rt].r<<' '<<c[c[rt].l].r<<endl;
st=max(st,c[c[c[rt].l].r].m_id);
// cout<<st<<endl;
}
void ask(int lx,int rx,int ly,int ry)
{
lx+=m1-1,rx+=m1+1;
// cout<<lx<<' '<<rx<<endl;
for (;!((lx^rx)==1);lx>>=1,rx>>=1) {
if ((lx&1)==0) doit(lx+1,ly,ry);
if ((rx&1)==1) doit(rx-1,ly,ry);
}
}
bool cmp2(int i,int j)
{
return w[i]<w[j];
}
bool cmp1(int i,int j)
{
return a[i].z<a[j].z;
}
int main()
{
// freopen("g.in","r",stdin);
// freopen("g.out","w",stdout);
scanf("%d",&n);
tot=0;
for (int i=1;i<=n;i++) {
scanf("%d%d%d%d%d",&a[i].lx,&a[i].rx,&a[i].ly,&a[i].ry,&a[i].z);
w[++tot]=a[i].lx,p[tot]=i;
w[++tot]=a[i].rx,p[tot]=i+n;
}
scanf("%d",&m);
b[0].w=b[m+1].w=oo;
for (int i=1;i<=m;i++) {
scanf("%d%d",&b[i].x,&b[i].y);b[i].w=i;
w[++tot]=b[i].x,p[tot]=i+n+n;
}
// cout<<b[194].x<<' '<<b[194].y<<endl;
for (int i=1;i<=tot;i++) u[i]=i;
sort(u+1,u+tot+1,cmp2);
w[u[0]=0]=-1;
for (int i=1,k=0;i<=tot;i++) {
if (w[u[i]]!=w[u[i-1]]) k++;
if (p[u[i]]<=n) a[p[u[i]]].lx=k;
else if (p[u[i]]<=n+n) a[p[u[i]]-n].rx=k;
else b[p[u[i]]-n-n].x=k;
}
origin();
for (int i=1;i<=m;i++) ins(b[i].x,b[i].y,i);
for (int i=1;i<=n;i++) u[i]=i;
sort(u+1,u+n+1,cmp1);
// memset(p,0,sizeof(p));
// cout<<ss<<endl;
// for (int i=1;i<=n;i++) cout<<a[i].lx<<' '<<a[i].rx<<endl;
for (int i=1;i<=n;i++) {
st=0;
ask(a[u[i]].lx,a[u[i]].rx,a[u[i]].ly,a[u[i]].ry);
// cout<<st<<endl;
// cout<<endl;
// if (p[st]) cout<<oo<<' '<<st<<' '<<b[st].x<<' '<<b[st].y<<' '<<b[st].w<<endl;
// if (st==194) cout<<endl;
if (st==0) continue;
p[st]=1;
ans[st]=u[i];
// cout<<b[st].y<<' '<<st<<endl;
del(b[st].x,b[st].y,st);
}
// cout<<ss<<' '<<m1<<endl;
for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}
快了1000ms+
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
const int oo=1073741819;
using namespace std;
struct node{
int y,id,l,r,m_id;
}c[7000000];
struct point{
int x,y,w;
}b[200000];
struct rect{
int lx,rx,ly,ry,z;
}a[200000];
int n,m,ss,ans[200000],st,ls[200000],rs[200000],root[5000000];
int w[500000],u[500000],p[500000],m1,tot;
int max(int x,int y)
{
if (b[x].w<b[y].w) return x;
return y;
}
void updata(int x)
{
c[x].m_id=max(c[x].id,c[c[x].l].m_id);
c[x].m_id=max(c[x].m_id,c[c[x].r].m_id);
}
int right(int x,int y)
{
c[y].l=c[x].r,c[x].r=y,updata(y);
return x;
}
int left(int x,int y)
{
c[y].r=c[x].l,c[x].l=y,updata(y);
return x;
}
void rconnect(int x)
{
if (!rs[0]) {rs[rs[0]=1]=x;return ;}
c[rs[rs[0]]].l=x,rs[++rs[0]]=x;
}
void lconnect(int x)
{
if (!ls[0]) {ls[ls[0]=1]=x;return ;}
c[ls[ls[0]]].r=x,ls[++ls[0]]=x;
}
int cmp(int x,int y,int id)
{
if (y!=c[x].y) return (y<c[x].y) ? -1 : 1;
if (id!=c[x].id) return (id<c[x].id) ? -1 : 1;
return 0;
}
void splay(int &mid,int y,int id)
{
int pd,tmp;
ls[0]=rs[0]=0;
for (;mid && ((pd=cmp(mid,y,id))!=0);) {
if (pd<0) {
if (c[mid].l && cmp(c[mid].l,y,id)<0) mid=right(c[mid].l,mid);
rconnect(mid),tmp=c[mid].l,c[mid].l=0,mid=tmp;
}
else if (pd>0) {
if (c[mid].r && cmp(c[mid].r,y,id)>0) mid=left(c[mid].r,mid);
lconnect(mid),tmp=c[mid].r,c[mid].r=0,mid=tmp;
}
}
if (!mid) {
mid=++ss;
c[ss].y=y,c[ss].id=id;
}
if (c[mid].l) lconnect(c[mid].l);
if (c[mid].r) rconnect(c[mid].r);
for (int i=ls[0];i>=1;i--) updata(ls[i]);
for (int i=rs[0];i>=1;i--) updata(rs[i]);
if (ls[0]) c[mid].l=ls[1];
if (rs[0]) c[mid].r=rs[1];
updata(mid);
}
void origin()
{
for (m1=1;m1<=tot+2;m1<<=1) ;
ss=0;
}
void ins(int x,int y,int id)
{
for (x+=m1;x;x>>=1)
splay(root[x],y,id);
}
void del(int x,int y,int id)
{
for (x+=m1;x;x>>=1) {
// cout<<ss<<endl;
// cout<<ss<<endl;
// cout<<root[x]<<' '<<c[root[x]].y<<' '<<c[root[x]].id<<' '<<y<<' '<<id<<endl;
splay(root[x],y,id);
b[id].w=oo;
updata(root[x]);
/* splay(root[x],y,id);
if (!c[root[x]].r) root[x]=c[root[x]].l;
else if (!c[root[x]].l) root[x]=c[root[x]].r;
else {
int k=c[root[x]].r;
for (;c[k].l;k=c[k].l) ;
splay(c[root[x]].r,c[k].y,c[k].id);
c[c[root[x]].r].l=c[root[x]].l;
root[x]=c[root[x]].r;
updata(root[x]);
}*/
}
}
void doit(int x,int ly,int ry)
{
splay(root[x],ry,m+1);
splay(c[root[x]].l,ly,0);
int rt=root[x];
// cout<<rt<<' '<<c[rt].l<<' '<<c[rt].r<<' '<<c[c[rt].l].r<<endl;
st=max(st,c[c[c[rt].l].r].m_id);
// cout<<st<<endl;
}
void ask(int lx,int rx,int ly,int ry)
{
lx+=m1-1,rx+=m1+1;
// cout<<lx<<' '<<rx<<endl;
for (;!((lx^rx)==1);lx>>=1,rx>>=1) {
if ((lx&1)==0) doit(lx+1,ly,ry);
if ((rx&1)==1) doit(rx-1,ly,ry);
}
}
bool cmp2(int i,int j)
{
return w[i]<w[j];
}
bool cmp1(int i,int j)
{
return a[i].z<a[j].z;
}
int main()
{
freopen("g.in","r",stdin);
freopen("g.out","w",stdout);
scanf("%d",&n);
tot=0;
for (int i=1;i<=n;i++) {
scanf("%d%d%d%d%d",&a[i].lx,&a[i].rx,&a[i].ly,&a[i].ry,&a[i].z);
w[++tot]=a[i].lx,p[tot]=i;
w[++tot]=a[i].rx,p[tot]=i+n;
}
scanf("%d",&m);
b[0].w=b[m+1].w=oo;
for (int i=1;i<=m;i++) {
scanf("%d%d",&b[i].x,&b[i].y);b[i].w=i;
w[++tot]=b[i].x,p[tot]=i+n+n;
}
// cout<<b[194].x<<' '<<b[194].y<<endl;
for (int i=1;i<=tot;i++) u[i]=i;
sort(u+1,u+tot+1,cmp2);
w[u[0]=0]=-1;
for (int i=1,k=0;i<=tot;i++) {
if (w[u[i]]!=w[u[i-1]]) k++;
if (p[u[i]]<=n) a[p[u[i]]].lx=k;
else if (p[u[i]]<=n+n) a[p[u[i]]-n].rx=k;
else b[p[u[i]]-n-n].x=k;
}
origin();
for (int i=1;i<=m;i++) ins(b[i].x,b[i].y,i);
for (int i=1;i<=n;i++) u[i]=i;
sort(u+1,u+n+1,cmp1);
// memset(p,0,sizeof(p));
// cout<<ss<<endl;
// for (int i=1;i<=n;i++) cout<<a[i].lx<<' '<<a[i].rx<<endl;
for (int i=1;i<=n;i++) {
st=0;
ask(a[u[i]].lx,a[u[i]].rx,a[u[i]].ly,a[u[i]].ry);
// cout<<st<<endl;
// cout<<endl;
// if (p[st]) cout<<oo<<' '<<st<<' '<<b[st].x<<' '<<b[st].y<<' '<<b[st].w<<endl;
// if (st==194) cout<<endl;
if (st==0) continue;
p[st]=1;
ans[st]=u[i];
// cout<<b[st].y<<' '<<st<<endl;
del(b[st].x,b[st].y,st);
}
// cout<<ss<<' '<<m1<<endl;
for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}