求卡常
查看原帖
求卡常
221575
LiuyuzhuoHB幻想积木楼主2021/5/9 18:11

写的两只log的算法

结果不开O270分,开O2最慢点948ms,不知道为什么这么慢

#include<bits/stdc++.h>
#define pii pair<int,int>
#define pu(x) qz[x].sz=qz[qz[x].ls].sz+qz[qz[x].rs].sz+1
using namespace std;
const int inf=2147483647;
int n,m,cnt,a[50001];
struct Node
{
    int qz;
    int ls;
    int rs;
    int sz;
    int rn;
    Node()
    {
        ls=rs=qz=0,sz=1,rn=rand();
    }
};
struct fhq_treap
{
    int rt;
    vector<Node>qz;
    int merg(int rt1,int rt2)
    {
        if(!rt1||!rt2)return rt1+rt2;
        else if(qz[rt1].rn<qz[rt2].rn)
        {
            qz[rt1].rs=merg(qz[rt1].rs,rt2);
            pu(rt1);
            return rt1;
        }
        else
        {
            qz[rt2].ls=merg(rt1,qz[rt2].ls);
            pu(rt2);
            return rt2;
        }
    }
    pii split_qz(int x,int now)//同样的划在左边
    {
        if(now==0)return make_pair(0,0);
        else if(qz[now].qz<=x)
        {
            pii a=split_qz(x,qz[now].rs);
            qz[now].rs=a.first;
            pu(now);
            return make_pair(now,a.second);
        }
        else
        {
            pii a=split_qz(x,qz[now].ls);
            qz[now].ls=a.second;
            pu(now);
            return make_pair(a.first,now);
        }
    }
    pii split_pm(int p,int now)//1-p名划
    {
        if(now==0)return make_pair(0,0);
        else if(qz[qz[now].ls].sz+1<=p)
        {
            pii a=split_pm(p-qz[qz[now].ls].sz-1,qz[now].rs);
            qz[now].rs=a.first;
            pu(now);
            return make_pair(now,a.second);
        }
        else
        {
            pii a=split_pm(p,qz[now].ls);
            qz[now].ls=a.second;
            pu(now);
            return make_pair(a.first,now);
        }
    }
    void ins(int x)
    {
        Node aa;
        aa.qz=x;
        qz.push_back(aa);
        if(!rt)
        {
            rt=qz.size()-1;
            return;
        }
        pii a=split_qz(x,rt);
        rt=merg(a.first,qz.size()-1);
        rt=merg(rt,a.second);
    }
    void del(int x)
    {
        if(qz[rt].sz==1)
        {
            rt=0;
            return;
        }
        pii a=split_qz(x-1,rt);
        pii b=split_pm(1,a.second);
        rt=merg(a.first,b.second);
    }
    int sm(int l,int r)
    {
        pii a=split_qz(r,rt);
        pii b=split_qz(l-1,a.first);
        int ans=qz[b.second].sz;
        rt=merg(b.first,b.second);
        rt=merg(rt,a.second);
        return ans;
    }
};
struct N
{
    fhq_treap ft;
    int ls,rs,l,r;
} p[500001];
int qzs_newnode(int l,int r)
{
    p[++cnt].l=l,p[cnt].r=r;
    Node aaa;
    aaa.sz=0;
    p[cnt].ft.qz.push_back(aaa);
    return cnt;
}
void ins(int qz,int wz,int now)
{
    //cout<<qz<<' '<<wz<<' '<<now<<' '<<p[now].l<<' '<<p[now].r<<endl;
    int ll=p[now].l,rr=p[now].r,mid=(ll+rr)/2;
    p[now].ft.ins(wz);
    if(ll==rr)return;
    if(qz<=mid)
    {
        if(!p[now].ls)p[now].ls=qzs_newnode(ll,mid);
        ins(qz,wz,p[now].ls);
    }
    else
    {
        if(!p[now].rs)p[now].rs=qzs_newnode(mid+1,rr);
        ins(qz,wz,p[now].rs);
    }
}
int qu_pm(int l,int r,int x,int m)
{
    if(p[m].r<x)
        return p[m].ft.sm(l,r);
    if(p[m].l>=x)
        return 0;
    int ans=0;
    if(p[m].ls)ans+=qu_pm(l,r,x,p[m].ls);
    if(p[m].rs) ans+=qu_pm(l,r,x,p[m].rs);
    return ans;
}
int qu_qz(int l,int r,int x,int m)
{
    //cout<<l<<' '<<r<<' '<<x<<' '<<p[m].l<<' '<<p[m].r<<endl;
    if(p[m].l==p[m].r)return p[m].l;
    if(!p[m].ls)return qu_qz(l,r,x,p[m].rs);
    int tt=p[p[m].ls].ft.sm(l,r);
    //cout<<p[m].l<<' '<<p[m].r<<' '<<tt<<endl;
    if(x<=tt)return qu_qz(l,r,x,p[m].ls);
    else return qu_qz(l,r,x-tt,p[m].rs);
}
void xg1(int wz,int la,int now)
{
    //cout<<p[now].l<<' '<<p[now].r<<' '<<la<<endl;
    p[now].ft.del(wz);
    if(p[now].l==p[now].r)return;
    if(la<=(p[now].l+p[now].r)/2)
        xg1(wz,la,p[now].ls);
    else
        xg1(wz,la,p[now].rs);
}
int main()
{
    //freopen("tt.out","w",stdout);
    qzs_newnode(0,2e8);
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; ++i)
    {
        scanf("%d",a+i);
        ins(a[i],i,1);
    }
    for(int i=1; i<=m; ++i)
    {
        int opt,l,r,x;
        scanf("%d",&opt);
        if(opt==1)
        {
            scanf("%d%d%d",&l,&r,&x);
            int pp=qu_pm(l,r,x,1);
            printf("%d\n",pp+1);
        }
        else if(opt==2)
        {
            scanf("%d%d%d",&l,&r,&x);
            int pp=qu_qz(l,r,x,1);
            printf("%d\n",pp);
        }
        else if(opt==3)
        {
            scanf("%d%d",&l,&x);
            xg1(l,a[l],1);
            a[l]=x;
            ins(a[l],l,1);
        }
        else if(opt==4)
        {
            scanf("%d%d%d",&l,&r,&x);
            int pm=qu_pm(l,r,x,1);
            if(!pm)
            {
                printf("-2147483647\n");
                continue;
            }
            int pp=qu_qz(l,r,pm,1);
            printf("%d\n",pp);
        }
        else if(opt==5)
        {
            scanf("%d%d%d",&l,&r,&x);
            int pm=qu_pm(l,r,x+1,1)+1;
            if(pm>r-l+1)
            {
                printf("2147483647\n");
                continue;
            }
            int pp=qu_qz(l,r,pm,1);
            printf("%d\n",pp);
        }
    }
}
2021/5/9 18:11
加载中...