【zkw线段树套自顶向下splay】cf44g

考场上队友写这道题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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值