听灌多,玄关
  • 板块灌水区
  • 楼主M_Jun
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/2/7 16:01
  • 上次更新2025/2/7 18:35:06
查看原帖
听灌多,玄关
1098953
M_Jun楼主2025/2/7 16:01

rt, link

样例过不了:

输入:

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

我的输出:

106465
106465
492737

应该的输出:

106465
84185
492737

我的代码:

#include <iostream>
#include <cstdio>
#include <random>
#include <time.h>

using namespace std ;

namespace OIfast {
	
	typedef long long lint ;
	typedef long double dint ;
	
	// 快读
	void read(lint &x) {
		char c ; bool b = true ;
		for (c = getchar() ; !isdigit(c) ; c = getchar())
			if (c == '-') b = false ;
		for (x = 0 ; isdigit(c) ; c = getchar())
			x = x * 10 + c - '0' ;
		if (b == false) x *= -1 ;
		return ;
	}
	
	// 快写
	void write(lint x) {
		if (x < 0) putchar('-'), x *= -1 ;
		if (x >= 10) write(x / 10) ;
		putchar(x % 10 + '0') ;
		return ;
	}
	
	// 快写组件
	void writer(lint x, char c) {
		write(x) ;
		putchar(c) ;
		return ;
	} 
}
namespace FHQ_Treap {
	
	typedef long long lint ;
	typedef long double dint ;
	
	struct Node {
		lint Size ;
		lint val, rnd ;
		lint Left, Right ;
	};
	
	lint root, idx ;
	vector<Node> tree ;
	
	// 创建新的节点
	lint get_Node(lint val) {
		idx ++ ;
		tree[idx].Size = 1 ;
		tree[idx].val = val ;
		tree[idx].rnd = rand() ;
		return idx ;
	}
	
	// 向上更新父节点
	void push_up(lint x) {
		Node &Now = tree[x] ;
		const Node &Leftson = tree[tree[x].Left] ;
		const Node &Rightson = tree[tree[x].Right] ;
		Now.Size = Leftson.Size + Rightson.Size + 1 ;
	}
	
	// 权值分裂: 当前在节点 now,将树分裂成以 x 为根(权值全部小于等于 k)、以 y 为根(权值全部大于 k)的两颗树
	void split(lint now, lint k, lint &x, lint &y) {
		if (!now) {x = y = 0 ; return ;}
		if (tree[now].val <= k) {
			x = now ;
			split(tree[now].Right, k, tree[now].Right, y) ;
		} else {
			y = now ;
			split(tree[now].Left, k, x, tree[now].Left) ;
		}
		push_up(now) ;
		return ;
	}
	
	// 排名分裂: 当前在节点 now,将树分裂成以 x 为根(权值全部小于等于 k)、以 y 为根(权值全部大于 k)的两颗树
	void division(lint now, lint k, lint &x, lint &y) {
		if (!now) {x = y = 0 ; return ;}
		if (k < tree[tree[now].Left].Size) {
			y = now ;
			lint son = tree[now].Left ;
			division(son, k, x, son) ;
		} else {
			x = now ;
			lint son = tree[now].Right ;
			division(son, k - tree[tree[now].Left].Size - 1, son, y) ;
		}
		push_up(now) ;
		return ;
	}
	
	// 合并: 合并以 x 为根和以 y 为根的两颗树(x 所有点的权值都小于 y 所有点的权值)
	lint merge(lint x, lint y) {
		if (!x || !y) return x | y ;
		if (tree[x].rnd < tree[y].rnd) {
			tree[x].Right = merge(tree[x].Right, y) ;
			push_up(x) ;
			return x ;
		} else {
			tree[x].Left = merge(x, tree[x].Left) ;
			push_up(y) ;
			return y ;
		}
	}
	
	// 插入: 插入权值为 val 的点
	void insert(lint val) {
		lint x, y ;
		split(root, val, x, y) ;
		root = merge(merge(x, get_Node(val)), y) ;
		return ;
	}
	
	// 区间删除: 删除给定权值为 val 的所有点
	void remove(lint val) {
		lint x, y, z ;
		split(root, val, x, z) ;
		split(x, val - 1, x, y) ;
		root = merge(x, z) ;
	}
	
	// 单点删除: 删除给定权值为 val 的其中一个点
	void Delete(lint val) {
		lint x, y, z ;
		split(root, val, x, z) ;
		split(x, val - 1, x, y) ;
		if (y) y = merge(tree[y].Left, tree[y].Right) ;
		root = merge(merge(x, y), z) ;
		return ;
	}
	
	// 求第 k 小的数
	lint kth(lint root, lint k) {
		lint now = root ;
		while (true) {
			if (k <= tree[tree[now].Left].Size) now = tree[now].Left ;
			else if (k == tree[tree[now].Left].Size + 1) return tree[now].val ;
			else {
				k -= tree[tree[now].Left].Size + 1 ;
				now = tree[now].Right ;
			}
		}
		return -1 ;
	}
	
	// 查询权值为 val 的节点的排名
	lint Rank(lint val) {
		lint x, y ;
		split(root, val - 1, x, y) ;
		lint res = tree[x].Size + 1 ;
		root = merge(x, y) ;
		return res ;
	}
	
	// 查询权值为 val 的节点的前驱
	lint Predecessor(lint val) {
		lint x, y ;
		split(root, val - 1, x, y) ;
		lint res = kth(x, tree[x].Size) ;
		root = merge(x, y) ;
		return res ;
	}
	
	// 查询权值为 val 的节点的后继
	lint Successor(lint val) {
		lint x, y ;
		split(root, val, x, y) ;
		lint res = kth(y, 1) ;
		root = merge(x, y) ;
		return res ;		
	}
}

using namespace OIfast ;
using namespace FHQ_Treap ;

const lint MAXN = 1e5 + 5 ;
const lint INF = 0x7fffffff ;

lint n ;
lint opt, a ;

signed main ( ) {
	
	read(n) ;
//	srand(time(NULL)) ;
	tree.resize(MAXN, Node()) ;
	for (lint i = 1 ; i <= n ; i ++) {
		read(opt), read(a) ;
		if (opt == 0) puts("Error !!!") ;
		else if (opt == 1) insert(a) ;
		else if (opt == 2) Delete(a) ;
		else if (opt == 3) insert(a), writer(Rank(a), '\n'), Delete(a) ;
		else if (opt == 4) writer(kth(root, a), '\n') ;
		else if (opt == 5) writer(Predecessor(a), '\n') ;
		else if (opt == 6) writer(Successor(a), '\n') ;
	}
	
	return 0 ;
}
2025/2/7 16:01
加载中...