社区讨论

线段树套非旋Treap不开O2 80分,开了后全部RE了求助为什么

P3380【模板】树套树参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mi7rl6te
此快照首次捕获于
2025/11/21 02:28
4 个月前
此快照最后确认于
2025/11/21 02:28
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
inline int read(){
    char ch=getchar();
    int res=0,f=1;
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    return res*f;
}
const int N=5000005;
const int inf=2147483647;
int n,m,a[N],mx;
namespace FHQ_Treap{
    int son[N][2],siz[N],val[N],key[N],tot;
    #define lc(u) son[u][0]
    #define rc(u) son[u][1]
    inline int addnode(int k){
        int u=++tot;
        val[tot]=k,key[tot]=rand();
        siz[tot]=1;return tot;
    }
    inline void pushup(int u){
        siz[u]=siz[lc(u)]+siz[rc(u)]+1;
    }
    void merge(int &u,int r1,int r2){
        if(!r1||!r2){u=r1+r2;return;}
        if(key[r1]<key[r2])u=r1,merge(rc(u),rc(r1),r2);
        else u=r2,merge(lc(u),r1,lc(r2));
        pushup(u);
    }
    void split(int u,int &r1,int &r2,int v){
        if(u==0){r1=r2=0;return;}
        if(val[u]<=v){
            r1=u,split(rc(u),rc(r1),r2,v);
        }
        else r2=u,split(lc(u),r1,lc(r2),v);
        pushup(u);
    }
    inline int getrk(int rt,int k){
        int r1,r2;
        split(rt,r1,r2,k-1);
        int res=siz[r1];
        merge(rt,r1,r2);
        return res;
    }
    inline int insert(int &rt,int v){
        int u=addnode(v),r1,r2;
        split(rt,r1,r2,v);
        merge(r1,r1,u);
        merge(rt,r1,r2);
    }
    inline int delet(int &rt,int v){
        int r1,r2,r3;
        split(rt,r1,r2,v);
        split(r1,r1,r3,v-1);
        merge(r3,lc(r3),rc(r3));
        merge(r1,r1,r3);
        merge(rt,r1,r2);
    }
    inline int pre(int rt,int v){
        int r1,r2;
        split(rt,r1,r2,v-1);
        if(!r1)return -inf;
        int u=r1;
        while(rc(u))u=rc(u);
        merge(rt,r1,r2);
        return val[u];
    }
    inline int nxt(int rt,int v){
        int r1,r2;
        split(rt,r1,r2,v);
        if(!r2)return inf;
        int u=r2;
        while(lc(u))u=lc(u);
        merge(rt,r1,r2);
        return val[u];
    }
    #undef lc
    #undef rc
}
using namespace FHQ_Treap;
namespace Seg{
    int rt[N];
    #define lc (u<<1)
    #define rc ((u<<1)|1)
    #define mid ((l+r)>>1)
    void buildtree(int u,int l,int r){
        for(int i=l;i<=r;++i)insert(rt[u],a[i]);
        if(l==r)return;
        buildtree(lc,l,mid);
        buildtree(rc,mid+1,r);
    }
    int queryrk(int u,int l,int r,int st,int des,int k){
        if(st<=l&&r<=des)return getrk(rt[u],k);
        int res=0;
        if(st<=mid)res+=queryrk(lc,l,mid,st,des,k);
        if(mid<des)res+=queryrk(rc,mid+1,r,st,des,k);
        return res;
    }
    void update(int u,int l,int r,int pos,int k){
        delet(rt[u],a[pos]),insert(rt[u],k);
        if(l==r)return;
        if(pos<=mid)update(lc,l,mid,pos,k);
        else update(rc,mid+1,r,pos,k);
    }
    int querypre(int u,int l,int r,int st,int des,int k){
        if(st<=l&&r<=des)return pre(rt[u],k);
        int res=-inf;
        if(st<=mid)res=max(res,querypre(lc,l,mid,st,des,k));
        if(mid<des)res=max(res,querypre(rc,mid+1,r,st,des,k));
        return res;
    }
    int querynxt(int u,int l,int r,int st,int des,int k){
        if(st<=l&&r<=des)return nxt(rt[u],k);
        int res=inf;
        if(st<=mid)res=min(res,querynxt(lc,l,mid,st,des,k));
        if(mid<des)res=min(res,querynxt(rc,mid+1,r,st,des,k));
    //	cout<<u<<" "<<l<<" "<<r<<" "<<res<<'\n';
        return res;
    }
}
using namespace Seg;
inline int kth(int st,int des,int k){
    int ans=0,l=0,r=mx+1;//cout<<k<<'\n';
    while(l<r){
        int pk=queryrk(1,1,n,st,des,mid);
    //	cout<<l<<r<<" "<<mid<<" "<<k<<'\n';
        if(pk<k)l=mid+1;
        else r=mid;
    }
    return l-1;
}
void write(int u){
    if(son[u][0])write(son[u][0]);
    cout<<val[u]<<" ";
    if(son[u][1])write(son[u][1]);
}
int main(){
//	freopen("my.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;i++)a[i]=read(),mx=max(mx,a[i]);
    buildtree(1,1,n);
//			cout<<2<<":";
//		write(rt[1]);puts("");
//	cout<<queryrk(2,1,5,1,4,2)<<'\n';return 0;
    for(int i=1;i<=m;i++){
        int op=read();
        switch(op){
            case 1:{
                int l=read(),r=read(),k=read();
                cout<<queryrk(1,1,n,l,r,k)+1<<'\n';
                break;
            }
            case 2:{
                int l=read(),r=read(),k=read();
                cout<<kth(l,r,k)<<'\n';
                break;
            }
            case 3:{
                int pos=read(),k=read();
                update(1,1,n,pos,k);a[pos]=k;
                break;
            }
            case 4:{
                int l=read(),r=read(),k=read();
                cout<<querypre(1,1,n,l,r,k)<<'\n';
                break;
            }
            case 5:{
                int l=read(),r=read(),k=read();
                cout<<querynx…

回复

2 条回复,欢迎继续交流。

正在加载回复...