C++代码CE玄关求调
  • 板块灌水区
  • 楼主M_Jun
  • 当前回复6
  • 已保存回复7
  • 发布时间2025/2/8 16:43
  • 上次更新2025/2/8 17:09:34
查看原帖
C++代码CE玄关求调
1098953
M_Jun楼主2025/2/8 16:43

rt:

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cctype>  // 包含 isdigit 函数的头文件
#include <random>
#include <vector>
#include <ctime>
#include <cmath>

namespace iofaster {
	typedef long long lint ;
	typedef long double dint ;
	
	// 快读 1.0
	lint read() {
		char c ; lint x ;
		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) x *= -1 ;
		return x ;
	}
	
	// 快读 2.0
	void input(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) x *= -1 ;
	}
	
	// 快写 1.0
	void write(lint x) {
		if (x < 0) putchar('-'), x *= -1 ;
		if (x >= 10) write(x / 10) ;
		putchar(x % 10 + '0') ;
	}
	
	// 快写 2.0
	void output(lint x, char c) {
		write(x) ;
		putchar(c) ;
	}
}

namespace FHQ_Treap {
	typedef long long lint ;
	typedef long double dint ;
	
	struct Node {
		lint Lazy ;
		lint Size ;
		lint val, rnd ;
		lint Left, Right ;
	} ;
	
	lint root, idx ;
	// 增大数组大小以避免越界风险
	Node tree[lint(2e6 + 5)] ; 
	
	// 创建新的节点
	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) {
		tree[x].Size = tree[tree[x].Left].Size + tree[tree[x].Right].Size + 1 ;
	}
	
	// 向下传播懒标记
	void push_down(lint x) {
		if (tree[x].Lazy) {
			std::swap(tree[x].Left, tree[x].Right) ;
			if (tree[x].Left) tree[tree[x].Left].Lazy ^= 1 ;
			if (tree[x].Right) tree[tree[x].Right].Lazy ^= 1 ;
			tree[x].Lazy = false ;
		}
	}
	
	// 权值分裂: 当前在节点 now,将树分裂成以 x 为根(权值全部小于等于 k)、以 y 为根(权值全部大于 k)的两颗树
	void split(lint now, lint k, lint &x, lint &y) {
		if (!now) {
			x = y = 0 ;
			return ;
		}
		push_down(now) ;
		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) ;
	}
	
	// 排名分裂: 当前在节点 now,将树分裂成以 x 为根(权值全部小于等于 k)、以 y 为根(权值全部大于 k)的两颗树
	void division(lint now, lint k, lint &x, lint &y) {
		if (!now) {
			x = y = 0 ;
			return ;
		}
		push_down(now) ;
		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) ;
	}
	
	// 合并: 合并以 x 为根和以 y 为根的两颗树(x 所有点的权值都小于 y 所有点的权值)
	lint merge(lint x, lint y) {
		if (!x || !y) return x | y ;
		if (tree[x].rnd < tree[y].rnd) {
			push_down(x) ;
			tree[x].Right = merge(tree[x].Right, y) ;
			push_up(x) ;
			return x ;
		} else {
			push_down(y) ;
			tree[y].Left = merge(x, tree[y].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) ;
	}
	
	// 区间删除: 删除给定权值为 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) ;
		y = merge(tree[y].Left, tree[y].Right) ;
		root = merge(merge(x, y), z) ;
	}
	
	// 区间翻转: 翻转排名从 l 到 r 的区间
	void reverse(lint l, lint r) {
		lint x, y, z ;
		division(root, l - 1, x, y) ;
		division(y, r - l + 1, y, z) ;
		tree[y].Lazy ^= 1 ;
		root = merge(merge(x, y), z) ;
	}
	
	// 求第 k 小的数
	lint kth(lint now, lint k) {
		while (now) {
			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 std ;
using namespace iofaster ;
using namespace FHQ_Treap ;

int main () {
	srand(time(NULL));  // 初始化随机数种子
	int n = read() ;  // 数列的大小
	int m = read() ;  // 操作的数量
	
	// 初始化数列
	for (int i = 0; i < n; ++ i) {
		int val = read() ;
		insert(val) ;
	}
	
	// 执行操作
	for (int i = 0 ; i < m ; ++ i) {
		int op = read() ;  // 操作类型
		if (op == 1) {  // 插入操作
			int val = read() ;
			insert(val) ;
		} else if (op == 2) {  // 删除操作
			int val = read() ;
			Delete(val) ;
		} else if (op == 3) {  // 区间反转操作
			int l = read() ;
			int r = read() ;
			reverse(l, r) ;
		}
	}
	return 0;
}
2025/2/8 16:43
加载中...