1 条题解

  • 0
    @ 2023-6-21 20:00:07

    C++ :

    #include <cstdio>
    
    using namespace std;
    
    const int SN = 1000000 + 10;
    
    int f[SN], ch[SN][2], key[SN], cnt[SN], size[SN];
    int sz, root;
    
    inline void Read(int &x) {
        int in = 0,f = 1;char ch = getchar();
        while(ch<'0' || ch>'9') {if(ch=='-') f = -1;ch = getchar();}
        while(ch>='0' && ch<='9') {in = in*10+ch-'0';ch = getchar();}
        x = in*f;
    }
    
    inline void clear(int x){
        f[x] = ch[x][0] = ch[x][1] = key[x] = size[x] = cnt[x] = 0;
    }
    
    inline int get(int x){
        return ch[f[x]][1] == x;
    }
    
    inline void update(int x) {
        if(x) {
    	size[x] = cnt[x];
    	if(ch[x][0]) size[x] += size[ch[x][0]];
    	if(ch[x][1]) size[x] += size[ch[x][1]];
        }	
    }
    
    inline void rotate(int x) {
        int fa = f[x], anc = f[fa], which = get(x);
        ch[fa][which] = ch[x][which^1], f[ch[fa][which]] = fa;
        f[x] = anc, f[fa] = x, ch[x][which^1] = fa;
        if(anc) ch[anc][ch[anc][1] == fa] = x;
        update(fa),update(x);
    }
    
    inline void splay(int x) {
        for(int fa;fa = f[x];rotate(x)) 
    	if(f[fa]) rotate((get(x)==get(fa))? fa: x);
        root = x;
    }
    
    inline int find(int x) {
        int now = root, ans = 0;
        while(1) {
    	if(x < key[now]) now = ch[now][0];
    	else {
    	    ans += ch[now][0]? size[ch[now][0]]: 0;
    	    if(x == key[now]) {splay(now);return ans + 1;}
    	    ans += cnt[now];
    	    now = ch[now][1];
    	}
        }
    }
    
    inline int findx(int x) {
        int now = root;
        while(1) {
    	if(ch[now][0] && x<=size[ch[now][0]]) now = ch[now][0];
    	else {
    	    int tmp = (ch[now][0]? size[ch[now][0]]: 0) + cnt[now];
    	    if(x <= tmp) {return key[now];}
    	    x -= tmp;now = ch[now][1];
    	}
        }
    }
    
    inline int pre() {
        int now = ch[root][0];
        while(ch[now][1]) now = ch[now][1];
        return now;
    }
    
    inline int net() {
        int now = ch[root][1];
        while(ch[now][0]) now = ch[now][0];
        return now;
    }
    
    inline void insert(int x) {
        if(root == 0) {
    	sz++;
    	ch[sz][0] = ch[sz][1] = f[sz] = 0;key[sz] = x,root = sz;
    	cnt[sz] = size[sz] = 1;
    	return ;
        }
        int now = root, fa = 0;
        while(1) {
    	if(key[now] == x) {cnt[now]++; update(now); update(fa);splay(now);return ;}
    	fa = now;
    	now = ch[now][x > key[now]];
    	if(now == 0) {
    	    sz++;
    	    ch[sz][0] = ch[sz][1] = 0;
    	    key[sz] = x, ch[fa][x > key[fa]] = sz, cnt[sz] = size[sz] = 1;
    	    f[sz] = fa;
    	    update(fa);
    	    splay(sz);
    	    return ;
    	}
        }
    }    
    
    inline void del(int x) {
        find(x);
        if(cnt[root] > 1) {cnt[root]--; update(root); return ;}
        if(!ch[root][1] && !ch[root][0]) { clear(root),root =0;return ;}
        if(!ch[root][1]) {
    	int anc = root; root = ch[root][0];
    	f[root] = 0;clear(anc);
    	return ;
        }
        else if(!ch[root][0]) {
    	int anc = root; root = ch[root][1];
    	f[root] = 0; clear(anc);
    	return ;
        }
        int left = pre(), anc = root;
        splay(left);
        ch[root][1] = ch[anc][1],f[ch[anc][1]] = root;
        clear(anc);
        update(root);
        return ;
    }
    
    int main() {
        int n, x, opt;
        Read(n);
        for(int i = 1; i <= n; i++) {
    	Read(opt),Read(x);
    	switch(opt) {
    	case 1: insert(x);break;
    	case 2: del(x);break;
    	case 3: printf("%d\n",find(x));break;
    	case 4: printf("%d\n",findx(x));break;
    	case 5: insert(x),printf("%d\n",key[pre()]),del(x);break;
    	case 6: insert(x),printf("%d\n",key[net()]),del(x);break;
    	}
        }
        return 0;
    }
    
    • 1

    信息

    ID
    1017
    时间
    10000ms
    内存
    256MiB
    难度
    (无)
    标签
    (无)
    递交数
    0
    已通过
    0
    上传者