树套树卡了?
查看原帖
树套树卡了?
380579
BMTXLRC楼主2022/6/11 13:30

有人用线段树+Treap/FHQ Treap卡过去吗

我的TLE 50pts,怎么卡都没用

//树套树
#include<bits/stdc++.h>
#define mid ((l+r)>>1)
using namespace std;
const int N=1e8+5,M=5e5+5;
const int inf=2147483647;
int n,m,f[M],cnt,root[M<<2];
struct FHQ_Treap{int pri,l,r,size,x;}a[N];
inline int read(){
    int x=0,s=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') s=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    return x*s;
}
inline void write(int x){
    if(abs(x)>=10) write(x/10);
    if(x<0&&abs(x)<=9) putchar('-');
    putchar(abs(x)%10+48);
}
inline void pushup(int now){
    a[now].size=a[a[now].l].size+a[a[now].r].size+1;
    return;
}
inline int new_node(int k){
    a[++cnt].pri=rand();
    a[cnt].size=1;
    a[cnt].x=k;
    return cnt;
}
inline void split(int now,int k,int &x,int &y){
    if(!now){
        x=y=0;
        return;
    }
    if(a[now].x<=k){
        x=now;
        split(a[now].r,k,a[now].r,y);
    }else{
        y=now;
        split(a[now].l,k,x,a[now].l);
    }
    pushup(now);
}
inline int merge(int x,int y){
    if(!x||!y) return x+y;
    if(a[x].pri<a[y].pri){
        a[x].r=merge(a[x].r,y);
        pushup(x);
        return x;
    }else{
        a[y].l=merge(x,a[y].l);
        pushup(y);
        return y;
    }
}
inline void insert(int now,int k){
    int x,y;
    split(root[now],k-1,x,y);
    root[now]=merge(merge(x,new_node(k)),y);
}
inline void remove(int now,int k){
    int x,y,z;
    split(root[now],k-1,x,y);
    split(y,k,y,z);
    y=merge(a[y].l,a[y].r);
    root[now]=merge(merge(x,y),z);
}
inline int Rank(int p,int k){
    int x,y;
    split(root[p],k-1,x,y);
    int ans=a[x].size;
    root[p]=merge(x,y);
    return ans;
}
// inline int kth(int now,int x){
//     while(1){
//         if(x<=a[a[now].l].size) now=a[now].l;
//         else if(x==a[a[now].l].size+1) return now;
//         else x-=a[a[now].l].size+1,now=a[now].r;
//     }
// }
// inline int FHQ_find_l(int now,int k){
//     int x,y,ans;
//     split(root[now],k-1,x,y);
//     if(a[x].size==0) ans=-inf;
//     else ans=a[kth(x,a[x].size)].x;
//     root[now]=merge(x,y);
//     return ans;
// }
// inline int FHQ_find_r(int now,int k){
//     int x,y,ans;
//     split(root[now],k,x,y);
//     if(a[y].size==0) ans=inf;
//     else ans=a[kth(y,1)].x;
//     root[now]=merge(x,y);
//     return ans;
// }
inline void build(int p,int l,int r){
    root[p]=0;
    for(register int i=l;i<=r;i++) insert(p,f[i]);
    if(l==r) return;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
}
inline int ask_kth(int p,int l,int r,int x,int y,int k){
    if(y<l||x>r) return 0;
    if(x<=l&&r<=y) return Rank(p,k);
    return ask_kth(p<<1,l,mid,x,y,k)+ask_kth(p<<1|1,mid+1,r,x,y,k);
}
inline int ask_rank(int x,int y,int k){
    int l=0,r=2e9,ans=-1;
    while(l<=r){
        if(ask_kth(1,1,n,x,y,mid)+1<=k) ans=mid,l=mid+1;
        else r=mid-1;
    }
    return ans;
}
inline void change(int p,int l,int r,int x,int k){
    remove(p,f[x]);
    insert(p,k);
    if(l==r) return;
    if(x<=mid) change(p<<1,l,mid,x,k);
    else change(p<<1|1,mid+1,r,x,k);
}
// inline int find_l(int p,int l,int r,int x,int y,int k){
//     if(l>y||x>r) return -inf;
//     if(x<=l&&r<=y) return FHQ_find_l(p,k);
//     return max(find_l(p<<1,l,mid,x,y,k),find_l(p<<1|1,mid+1,r,x,y,k));
// }
// inline int find_r(int p,int l,int r,int x,int y,int k){
//     if(l>y||x>r) return inf;
//     if(x<=l&&r<=y) return FHQ_find_r(p,k);
//     return min(find_r(p<<1,l,mid,x,y,k),find_r(p<<1|1,mid+1,r,x,y,k));
// }
int main(){
    n=read(),m=read();
    for(register int i=1;i<=n;i++) f[i]=read();
    build(1,1,n);
    for(register int i=1;i<=m;i++){
        int x,y,k;
        char op=getchar();
        while(op<'A'||op>'Z') op=getchar();
        if(op=='Q') x=read(),y=read(),k=read(),write(ask_rank(x,y,k)),puts("");
        else x=read(),y=read(),change(1,1,n,x,y),f[x]=y;
        // op=read(),x=read(),y=read();
        // if(op==1) k=read(),write(ask_kth(1,1,n,x,y,k)+1);
        // if(op==2) k=read(),write(ask_rank(x,y,k));
        // if(op==3) change(1,1,n,x,y),f[x]=y;
        // if(op==4) k=read(),write(find_l(1,1,n,x,y,k));
        // if(op==5) k=read(),write(find_r(1,1,n,x,y,k));
        // if(op!=3) puts("");
    }
}
2022/6/11 13:30
加载中...