树套树 TLE 40 求助
查看原帖
树套树 TLE 40 求助
246954
xj22yangyichen楼主2023/8/26 19:18
#include<time.h>
#include<random>
#include<stdio.h>
#include<ctype.h>
#include<algorithm>
#define N 100001
using namespace std;

inline int read(){
	int ans = 0;
	char ch = getchar();
	while(!isdigit(ch)){
		ch = getchar();
	}
	while(isdigit(ch)){
		ans *= 10;
		ans += ch ^ 48;
		ch = getchar();
	}
	return ans;
}
inline void write(int n){
	if(n > 9) write(n / 10);
	putchar(48 ^ n % 10);
}

mt19937 rnd(time(0));

struct treap{
	struct Node{
		int val, cnt,siz;
		unsigned pri;
		Node *lc, *rc;
		Node(int val_){
			val = val_;
			cnt = siz = 1;
			pri = rnd();
			lc = rc = nullptr;
		}
		inline void update(){
			siz = cnt;
			if(lc != nullptr){
				siz += lc->siz;
			}
			if(rc != nullptr){
				siz += rc->siz;
			}
		}
	}*root;
	
	pair<Node*, Node*> split_by_val(Node *rt, int x){
		if(rt == nullptr){
			return make_pair(nullptr, nullptr);
		}
		if(rt->val <= x){
			pair<Node*, Node*> tmp = split_by_val(rt->rc, x);
			rt->rc = tmp.first;
			rt->update();
			return make_pair(rt, tmp.second);
		} else {
			pair<Node*, Node*> tmp = split_by_val(rt->lc, x);
			rt->lc = tmp.second;
			rt->update();
			return make_pair(tmp.first, rt);
		}
	}
	
	Node* merge(Node *l, Node *r){
		if(l == nullptr && r == nullptr){
			return nullptr;
		} else if(l == nullptr){
			return r;
		} else if(r == nullptr){
			return l;
		} else {
			if(l->pri > r->pri){
				r->lc = merge(l, r->lc);
				r->update();
				return r;
			} else {
				l->rc = merge(l->rc, r);
				l->update();
				return l;
			}
		}
	}
	
	void insert(int x){
		pair<Node*, Node*> tmp1 = split_by_val(root, x);
		pair<Node*, Node*> tmp2 = split_by_val(tmp1.first, x - 1);
		Node *tmp3;
		if(tmp2.second != nullptr){
			tmp2.second->cnt++;
			tmp2.second->update();
			tmp3 = merge(tmp2.first, tmp2.second);
		} else {
			Node *p = new Node(x);
			tmp3 = merge(tmp2.first, p);
		}
		root = merge(tmp3, tmp1.second);
	}
	
	void erase(int x){
		pair<Node*, Node*> tmp1 = split_by_val(root, x);
		pair<Node*, Node*> tmp2 = split_by_val(tmp1.first, x - 1);
		if(tmp2.second->cnt == 1){
			if(tmp1.first == tmp2.second){
				tmp1.first = nullptr;
			}
			delete tmp2.second;
			tmp2.second = nullptr;
		} else {
			tmp2.second->cnt--;
			tmp2.second->update();
			tmp2.first = merge(tmp2.first, tmp2.second);
		}
		root = merge(tmp2.first, tmp1.second);
	}
	
	int query_rk(Node *rt, int x){
		pair<Node*, Node*> tmp = split_by_val(rt, x - 1);
		int ans = 1;
		if(tmp.first != nullptr){
			ans += tmp.first->siz;
		}
		rt = merge(tmp.first, tmp.second);
		return ans;
	}
};

int n, m, a[N], lsh[N << 1], cnt;
struct opt{
	char type;
	int x, y, k;
}op[N];

struct segtree{
	#define lc rt << 1
	#define rc rt << 1 | 1
	
	treap node[N << 3];
	
	void insert(int rt, int l, int r, int pos, int k){
		node[rt].insert(k);
		if(l == r){
			return;
		}
		int mid = (l + r) >> 1;
		if(pos <= mid) insert(lc, l, mid, pos, k);
		else insert(rc, mid + 1, r, pos, k);
	}
	
	void erase(int rt, int l, int r, int pos, int k){
		node[rt].erase(k);
		if(l == r){
			return;
		}
		int mid = (l + r) >> 1;
		if(pos <= mid) erase(lc, l, mid, pos, k);
		else erase(rc, mid + 1, r, pos, k);
	}
	
	int query(int rt, int l, int r, int L, int R, int k){
		if(l == r){
			return l;
		}
		int mid = (l + r) >> 1;
		int tmp = node[lc].query_rk(node[lc].root, R + 1)
				- node[lc].query_rk(node[lc].root, L);
		if(tmp >= k) return query(lc, l, mid, L, R, k);
		else return query(rc, mid + 1, r, L, R, k - tmp);
	}
	
	#undef lc
	#undef rc
}tree;

int main(){
	n = read(), m = read();
	for(int i = 1; i <= n; ++i){
		a[i] = read();
		lsh[++cnt] = a[i];
	}
	
	for(int i = 1; i <= m; ++i){
		op[i].type = getchar();
		if(op[i].type == 'C'){
			op[i].x = read(), op[i].k = read();
			lsh[++cnt] = op[i].k;
		} else {
			op[i].x = read(), op[i].y = read(), op[i].k = read();
		}
	}
	
	sort(lsh + 1, lsh + cnt + 1);
	cnt = unique(lsh + 1, lsh + cnt + 1) - lsh;
	
	for(int i = 1; i <= n; ++i){
		int tmp = lower_bound(lsh + 1, lsh + cnt, a[i]) - lsh;
		tree.insert(1, 1, cnt, tmp, i);
	}
	
	for(int i = 1; i <= m; ++i){
		if(op[i].type == 'C'){
			int tmp = lower_bound(lsh + 1, lsh + cnt, a[op[i].x]) - lsh;
			tree.erase(1, 1, cnt, tmp, op[i].x);
			tmp = lower_bound(lsh + 1, lsh + cnt, op[i].k) - lsh;
			tree.insert(1, 1, cnt, tmp, op[i].x);
			a[op[i].x] = op[i].k;
		} else {
			write(lsh[tree.query(1, 1, cnt, op[i].x, op[i].y, op[i].k)]);
			putchar(10);
		}
	}
	return 0;
}
2023/8/26 19:18
加载中...