萌新刚学OI求助
查看原帖
萌新刚学OI求助
663976
Broken_Eclipse楼主2022/10/9 10:38

fhq treap 90pts TLE on #9

参考了讨论区所说的分裂时父节点清零的问题,可是改动之后仍然没有效果。

救救孩子

#include <cstdio>
#include <random>
#include <algorithm>
#define Reg register
#define lson(x) tr[x].ls
#define rson(x) tr[x].rs
#define fa(x) tr[x].fa
using namespace std;
const int maxn=101000;
int n,tot,root,Ider[maxn];
struct node{
    int id,val;
    bool operator <(const node &A) const{
        if(val==A.val) return id<A.id;
        return val<A.val;
    }
}a[maxn];
struct FHQ_Treap{
    int ls,rs,lz,siz,dat,fa,val;
}tr[maxn];
inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<1)+(s<<3)+(ch^48);
        ch=getchar();
    }
    return s*w;
}
inline void dosth(int rt){
    if(!rt) return;
    tr[rt].lz^=1;
    swap(lson(rt),rson(rt));
}
inline void pushdown(int rt){
    if(tr[rt].lz){
        dosth(lson(rt)),dosth(rson(rt));
        tr[rt].lz=0;
    }
}
inline void pushup(int rt){
    tr[rt].siz=tr[lson(rt)].siz+tr[rson(rt)].siz+1;
    fa(lson(rt))=rt;
    fa(rson(rt))=rt;
}
inline void cleared(int rt){
    if(rt!=root) cleared(fa(rt));
    pushdown(rt);
}
inline int Findsiz(int rt){
    cleared(rt);
    int res=tr[lson(rt)].siz+1;
    while(rt!=root){
        if(rt==rson(fa(rt))) res+=tr[lson(fa(rt))].siz+1;
        rt=fa(rt);
    }
    return res;
}
inline void Split(int rt,int k,int &x,int &y){
    if(!rt) return x=0,y=0,void();
    pushdown(rt);
    if(k>tr[lson(rt)].siz) x=rt,Split(rson(rt),k-tr[lson(rt)].siz-1,rson(rt),y);
    else y=rt,Split(lson(rt),k,x,lson(rt));
    pushup(rt);
}
inline int Merge(int u,int v){
    if(!u|!v) return u|v;
    if(tr[u].dat<tr[v].dat){
        pushdown(u);
        rson(u)=Merge(rson(u),v);
        pushup(u);
        return u;
    }else{
        pushdown(v);
        lson(v)=Merge(u,lson(v));
        pushup(v);
        return v;
    }
}
inline void update(int l,int r){
    int x=0,y=0,z=0;
    Split(root,r,x,y);
    Split(x,l-1,x,z);
    fa(x)=fa(y)=fa(z)=0;
    dosth(z);
    x=Merge(x,z);
    root=Merge(x,y);
}
inline int build(int l,int r){
    if(l>r) return 0;
    int mid=(l+r)>>1,dir=++tot;
    tr[dir].dat=rand();
    Ider[mid]=dir;
    tr[dir].siz=1;
    tr[dir].val=a[mid].val;
    lson(dir)=build(l,mid-1);
    rson(dir)=build(mid+1,r);
    pushup(dir);
    return dir;
}
int main(){
    srand(time(0));
    n=read();
    for(Reg int i=1;i<=n;++i) a[i].val=read(),a[i].id=i;
    root=build(1,n);
    sort(a+1,a+1+n);
    for(Reg int i=1;i<=n;++i){
        int p=Findsiz(Ider[a[i].id]);
        printf("%d ",p);
        update(i,p);
    }
    printf("\n");
    return 0; 
}
2022/10/9 10:38
加载中...