简单版过了,数据加强版wa+mle,代码求调

P6136 【模板】普通平衡树(数据加强版)

Q__A__Q @ 2023-08-31 23:20:56

// Problem: P6136 【模板】普通平衡树(数据加强版)
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P6136
// Memory Limit: 89 MB
// Time Limit: 3000 ms
// Author: fzy
//
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
// #pragma GCC optimize(2)
using namespace std;
typedef long long ll;
#define int ll

const int maxn=1e5+10;
const int inf=2000000005;
int n,m,ans;

inline int read() {
    int s=0,w=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-')w=-1;
        ch=getchar();
    }
    while(isdigit(ch)) s=s*10+ch-'0',ch=getchar();
    return s*w;
}

inline void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

int siz[maxn],val[maxn],pri[maxn],num[maxn],ls[maxn],rs[maxn],tot=0;
int root=0;
mt19937 rnd(time(0));

inline void pushup(int rt) {
    siz[rt]=siz[ls[rt]]+siz[rs[rt]]+num[rt];
}

inline void lrotate(int &rt) {
    int t=rs[rt];
    rs[rt]=ls[t];
    ls[t]=rt;
    pushup(rt),pushup(t);
    rt=t;
}

inline void rrotate(int &rt) {
    int t=ls[rt];
    ls[rt]=rs[t];
    rs[t]=rt;
    pushup(rt),pushup(t);
    rt=t;
}

inline void ins(int &rt,int k) {
    if(!rt) {
        rt=++tot;
        val[rt]=k;
        pri[rt]=rnd()%inf;
        num[rt]=siz[rt]=1;
        return;
    }
    if(val[rt]==k) {
        num[rt]++;
        siz[rt]++;
        return;
    }
    if(val[rt]>k) {
        ins(ls[rt],k);
        if(pri[ls[rt]]<pri[rt]) rrotate(rt);
    } else {
        ins(rs[rt],k);
        if(pri[rs[rt]]<pri[rt]) lrotate(rt);
    }
    pushup(rt);
}

inline void del(int &rt,int k) {
    if(!rt) return;
    if(val[rt]<k) del(rs[rt],k);
    else if(val[rt]>k) del(ls[rt],k);
    else {
        if(num[rt]>1) num[rt]--,siz[rt]--;
        else if(!ls[rt]||!rs[rt]) rt=ls[rt]+rs[rt];
        else if(pri[ls[rt]]<pri[rs[rt]]) rrotate(rt),del(rt,k);
        else lrotate(rt),del(rt,k);
    }
    pushup(rt);
}

inline int findpre(int rt,int k) {
    if(!rt) return -inf;
    else if(val[rt]>=k) findpre(ls[rt],k);
    else return max(findpre(rs[rt],k),val[rt]);
}

inline int findsuf(int rt,int k) {
    if(!rt) return inf;
    else if(val[rt]<=k) findsuf(rs[rt],k);
    else return min(findsuf(ls[rt],k),val[rt]);
}

inline int findkth(int rt,int k) {
    if(!rt) return 0;
    if(siz[ls[rt]]>=k) findkth(ls[rt],k);
    else if(k>siz[ls[rt]]+num[rt]) findkth(rs[rt],k-siz[ls[rt]]-num[rt]);
    else return val[rt];
}

inline int findrnk(int rt,int k) {
    if(!rt) return 1;
    else if(val[rt]==k) return siz[ls[rt]]+1;
    else if(val[rt]<k) return siz[ls[rt]]+num[rt]+findrnk(rs[rt],k);
    else findrnk(ls[rt],k);
}

signed main() {
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    m=read(),n=read();
    for(int i=1; i<=m; ++i) {
        int x=read();
        ins(root,x);
    }
    int lst=0;
    while(n--) {
        int opt=read(),x=read();
        x=x^lst;
        if(opt==1) ins(root,x);
        else if(opt==2) del(root,x);
        else if(opt==3) lst=findrnk(root,x),ans^=lst;
        else if(opt==4) lst=findkth(root,x),ans^=lst;
        else if(opt==5) lst=findpre(root,x),ans^=lst;
        else lst=findsuf(root,x),ans^=lst;
    }
    write(ans);
    return 0;
}

by Q__A__Q @ 2023-08-31 23:26:52

改了一下函数返回值,现在20pts

// Problem: P6136 【模板】普通平衡树(数据加强版)
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P6136
// Memory Limit: 89 MB
// Time Limit: 3000 ms
// Author: fzy
//
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
// #pragma GCC optimize(2)
using namespace std;
typedef long long ll;
#define int ll

const int maxn=1e5+10;
const int inf=2000000005;
int n,m;

inline int read() {
    int s=0,w=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-')w=-1;
        ch=getchar();
    }
    while(isdigit(ch)) s=s*10+ch-'0',ch=getchar();
    return s*w;
}

inline void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

int siz[maxn],val[maxn],pri[maxn],num[maxn],ls[maxn],rs[maxn],tot=0;
int root=0;
mt19937 rnd(time(0));

inline void pushup(int rt) {
    siz[rt]=siz[ls[rt]]+siz[rs[rt]]+num[rt];
}

inline void lrotate(int &rt) {
    int t=rs[rt];
    rs[rt]=ls[t];
    ls[t]=rt;
    pushup(rt),pushup(t);
    rt=t;
}

inline void rrotate(int &rt) {
    int t=ls[rt];
    ls[rt]=rs[t];
    rs[t]=rt;
    pushup(rt),pushup(t);
    rt=t;
}

inline void ins(int &rt,int k) {
    if(!rt) {
        rt=++tot;
        val[rt]=k;
        pri[rt]=rnd()%inf;
        num[rt]=siz[rt]=1;
        return;
    }
    if(val[rt]==k) {
        num[rt]++;
        siz[rt]++;
        return;
    }
    if(val[rt]>k) {
        ins(ls[rt],k);
        if(pri[ls[rt]]<pri[rt]) rrotate(rt);
    } else {
        ins(rs[rt],k);
        if(pri[rs[rt]]<pri[rt]) lrotate(rt);
    }
    pushup(rt);
}

inline void del(int &rt,int k) {
    if(!rt) return;
    if(val[rt]<k) del(rs[rt],k);
    else if(val[rt]>k) del(ls[rt],k);
    else {
        if(num[rt]>1) num[rt]--,siz[rt]--;
        else if(!ls[rt]||!rs[rt]) rt=ls[rt]+rs[rt];
        else if(pri[ls[rt]]<pri[rs[rt]]) rrotate(rt),del(rt,k);
        else lrotate(rt),del(rt,k);
    }
    pushup(rt);
}

inline int findpre(int rt,int k) {
    if(!rt) return -inf;
    else if(val[rt]>=k) return findpre(ls[rt],k);
    else return max(findpre(rs[rt],k),val[rt]);
}

inline int findsuf(int rt,int k) {
    if(!rt) return inf;
    else if(val[rt]<=k) return findsuf(rs[rt],k);
    else return min(findsuf(ls[rt],k),val[rt]);
}

inline int findkth(int rt,int k) {
    if(!rt) return 0;
    if(siz[ls[rt]]>=k) return findkth(ls[rt],k);
    else if(k>siz[ls[rt]]+num[rt]) return findkth(rs[rt],k-siz[ls[rt]]-num[rt]);
    else return val[rt];
}

inline int findrnk(int rt,int k) {
    if(!rt) return 1;
    else if(val[rt]==k) return siz[ls[rt]]+1;
    else if(val[rt]<k) return siz[ls[rt]]+num[rt]+findrnk(rs[rt],k);
    else return findrnk(ls[rt],k);
}

signed main() {
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    n=read(),m=read();
    for(int i=1; i<=n; ++i) {
        int x=read();
        ins(root,x);
    }
    int lst=0,ans=0;
    while(m--) {
        int opt=read(),x=read();
        x=x^lst;
        if(opt==1) ins(root,x);
        else if(opt==2) del(root,x);
        else if(opt==3) lst=findrnk(root,x),ans^=lst;
        else if(opt==4) lst=findkth(root,x),ans^=lst;
        else if(opt==5) lst=findpre(root,x),ans^=lst;
        else lst=findsuf(root,x),ans^=lst;
    }
    write(ans);
    return 0;
}

by Q__A__Q @ 2023-08-31 23:46:24

找到问题了,数组开小了 wssb


by NaNO2_Cabbage @ 2023-09-03 17:10:44

6


by NaNO2_Cabbage @ 2023-09-03 19:51:14

寄数组开小了RE连个点

警示后人 数组要开够


by 262620zzj @ 2023-11-12 22:20:30

@NaNO2_Cabbage 数组开够了mle怎么办!


by NaNO2_Cabbage @ 2023-11-12 22:30:56

@262620zzj 我写的fhq-treap开了2e6


|