• 替罪羊树


    替罪羊树

    暴力重构的思想,如果树不够平衡,那么就拍扁重构即可

    和 treap 的操作大致都一样就是了,但常数挺小的,可以卡常使用

    const int N = 2005000;
    struct node {
    	int ls, rs, siz, sum;
    	int key, val;
    	#define key(k) p[k].key
    	#define val(k) p[k].val
    	#define ls(k) p[k].ls
    	#define rs(k) p[k].rs
    	#define siz(k) p[k].siz
    	#define sum(k) p[k].sum
    }p[N];
    int rt, cnt;
    const double A = 0.8;
    bool judge(int k) {
    	return val(k) && A * siz(k) < max(siz(ls(k)), siz(rs(k)));
    }
    
    void update(int k) {
    	siz(k) = siz(ls(k)) + siz(rs(k)) + (val(k) ? 1 : 0);
    	sum(k) = sum(ls(k)) + sum(rs(k)) + val(k);
    }
    
    int st[N], tp;
    void pia(int k) {
    	if (ls(k)) pia(ls(k));
    	if (val(k)) st[++tp] = k;
    	if (rs(k)) pia(rs(k));
    	return;
    }
    
    int rebuild(int l, int r) {
    	if (l > r) return 0;
    	int mid = (l + r) >> 1;
    	ls(st[mid]) = rebuild(l, mid - 1);
    	rs(st[mid]) = rebuild(mid + 1, r);
    	return update(st[mid]), st[mid];
    }
    int maintain(int p) {
    	return tp = 0, pia(p), rebuild(1, tp);
    }
    void insert(int &x, int val) {
    	if (!x) {
    		x = ++cnt, key(x) = val;
    		val(x) = siz(x) = sum(x) = 1;
    	}
    	else {
    		if (key(x) == val) val(x)++;
    		else if (val < key(x)) insert(ls(x), val);
    		else insert(rs(x), val);
    		update(x); judge(x) && (x = maintain(x));
    	}
    }
    void del(int &x, int val) {
    	sum(x)--;
    	if (key(x) == val) val(x)--;
    	else key(x) > val ? del(ls(x), val) : del(rs(x), val);
    	update(x), judge(x) && (x = maintain(x));
    }
    int rkup(int x, int k) {
    	int nw = 0;
    	while (1) {
    		if (!x) return nw;
    		if (key(x) == k) return nw + sum(ls(x)) + val(x);
    		if (key(x) <= k) nw += sum(ls(x)) + val(x), x = rs(x);
    		else x = ls(x);
    	}
    }
    int rkdw(int x, int k) {
    	int nw = 1;
    	while (1) {
    		if (!x) return nw;
    		if (key(x) == k) return nw + sum(ls(x));
    		if (key(x) <= k) nw += sum(ls(x)) + val(x), x = rs(x);
    		else x = ls(x);
    	}
    }
    
    int get(int k) {
    	int x = rt;
    	while (1) {
    		if (sum(ls(x)) >= k) x = ls(x);
    		else if (sum(ls(x)) + val(x) >= k) return key(x);
    		else k -= sum(ls(x)) + val(x), x = rs(x);
    	}
    	return 1;
    }
    
    int n, t, x, m, las, ans;
    int main() {
    	for (read(n), read(m); n; n--) 
    		read(x), insert(rt, x);
    	for (; m; m--) {
    		read(t), read(x), x ^= las;
    		if (t == 1) insert(rt, x);
    		else if (t == 2) del(rt, x);
    		else if (t == 3) las = rkdw(rt, x);
    		else if (t == 4) las = get(x);
    		else if (t == 5) las = get(rkdw(rt, x) - 1);
    		else las = get(rkup(rt, x) + 1);
    		if (t >= 3) ans ^= las;
    	}
    	write(ans);
    	return 0;
    }
    
  • 相关阅读:
    【腾讯Bugly干货分享】移动互联网测试到质量的转变
    【腾讯Bugly干货分享】微信终端跨平台组件 mars 系列(一)
    如何用手机维护Mysql数据库
    企业内网信息安全实践-记ChinaUnix技术交流
    完成《Java编程入门》初稿
    Windows Server 2012下安装Hyper-V虚拟机
    MacOSX和Windows 8的完美融合
    Iphone5S 体验(视频+截图)
    PC上安装MAC X Lion
    正宗PC Unix实验环境
  • 原文地址:https://www.cnblogs.com/Hs-black/p/13362704.html
Copyright © 2020-2023  润新知