板子合集
板子索引 可在右侧列表快捷跳转
火车头
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <bitset>
#include <algorithm>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <vector>
#include <queue>
#include <stack>
#include <sstream>
#include <cstring>
#include <string>
#include <cstdlib>
#define FOR(i, m, n) for (long long i = m; i <= n; i++)
#define FRO(i, m, n) for (long long i = m; i >= n; i--)
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define mp(a, b) make_pair(a, b)
#define INF 2147483647
#define INFF 0x3f3f3f3f3f3f3f3f
#define INFFF 0x7fffffffffffffff
using namespace std;
default
int main(){
return 0;
}
FR(Fast Read)
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
optimize优化
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
/*---基础优化结束---*/
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
二分 & 三分 search
//二分
int l, r, mid;
while (l < r) {
mid = (l + r /* + 1*/) >> 1; //手推一下 l + 1 == r 的情况,考虑是否加一
if (check(mid)) r = mid;
else l = mid + 1;
}
//精度二分
double l, r, mid, eps;
while (l + eps < r) {
mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid + eps;
}
//三分求f最小值(最大值改一改)
//最优的三分不是均匀分成3块,而是在mid左右两侧取值,这样显然更快。
int l, r, mid;
while (r - l >= 3) {
mid = (l + r) >> 1;
if (f(mid) > f(mid + 1)) l = mid + 1;
else r = mid;
}
//为了避免边界错误,分到只剩3个数就枚举一遍。
int ans, tmp = INT_MAX;
for (int i = l; i <= r; i++) {
if (f(i) < tmp) {
ans = i;
tmp = f(i);
}
}
单调栈 & 单调队列
单调栈一般维护当前节点往前找到的第一个小于/大于它的点,分别对应递增栈/递减栈。
//递增栈
stack<int> s;
for (int i = 1; i <= n; i++) {
while (!s.empty() && num[s.top()] >= num[i]) s.pop();
min_left[i] = s.top();
s.push(i);
}
//min_left中存储向左第一个小于它的节点的下标。
单调队列一般维护当前节点往前找m个点的最大/小值,分别对应递增队列/递减队列。一般用 deque 实现。
//递增队列
while (!q.empty()) q.pop_back();
num[0] = num[n + 1] = inf;
q.push_back(0);
for (int i = 1; i < k; i++) {
while (!q.empty() && num[q.back()] >= num[i]) q.pop_back();
q.push_back(i);
}
for (int i = k; i <= n; i++) {
while (!q.empty() && num[q.back()] >= num[i]) q.pop_back();
q.push_back(i);
while (!q.empty() && q.front() < i - k + 1) q.pop_front();
minium[i - k + 1] = num[q.front()];
}
普通树状数组
//long long !!!
#define lowbit(x) ((x) & (-x))
int c[maxn];
int ask(int pos){
int res = 0;
while(pos) {
res += c[pos];
pos -= lowbit(pos);
}
return res;
}
void update(int pos, int x){
while(pos <= n){
c[pos] += x;
pos += lowbit(pos);
}
}
二维树状数组
int c[maxn][maxn];
int ask(int pos_i, int pos_j) {
int res = 0;
for (int i = pos_i; i; i -= lowbit(i))
for (int j = pos_j; j; j -= lowbit(j))
res += c[i][j];
return res;
}
void update(int pos_i, int pos_j, int x) {
for (int i = pos_i; i <= n; i += lowbit(i))
for (int j = pos_j; j <= m; j += lowbit(j))
c[i][j] += x;
}
线段树
int n, m;
long long a[maxn];
struct node;
typedef node* pos;
pos new_node(int l, int r);
struct node {
private:
void push_up() { val = ls -> val + rs -> val; /*可以更改*/ }
void update_one(int x) { tag += x; val += x * (r - l + 1); /*可以更改*/ }
void push_down() { ls -> update_one(tag); rs -> update_one(tag); tag = 0; }
public:
int l, r;
long long val, tag;
pos ls, rs;
node() {
l = r = val = tag = 0;
ls = rs = NULL;
}
void build() {
if (l == r) { val = a[l]; /*可以更改*/ return; }
int mid = (l + r) >> 1;
ls = new_node(l, mid); ls -> build();
rs = new_node(mid + 1, r); rs -> build();
push_up();
}
void update(int _l, int _r, long long x) {
if (l >= _l && r <= _r) { update_one(x); return; }
push_down();
int mid = (l + r) >> 1;
if (mid >= _l) ls -> update(_l, _r, x);
if (mid + 1 <= _r) rs -> update(_l, _r, x);
push_up();
}
long long ask(int _l, int _r) {
if (l >= _l && r <= _r) { return val; }
push_down();
int mid = (l + r) >> 1; long long res = 0;
if (mid >= _l) res += /*可以更改*/ ls -> ask(_l, _r);
if (mid + 1 <= _r) res += /*可以更改*/ rs -> ask(_l, _r);
return res;
}
};
node buf[maxn * 2];
pos root = buf, buf_pos = buf;
pos new_node(int l, int r) {
pos p = ++buf_pos;
p -> ls = p -> rs = buf;
p -> l = l, p -> r = r;
return p;
}
DSU
const int maxn=5010;
int fa[maxn];
int find(int x) {
if(x!=fa[x])
fa[x]=find(fa[x]);
return fa[x];
}
void connect(int x, int y){
int c=find(x);
int d=find(y);
fa[c]=d;
}
int main(){
ll n,m,p;
cin>>n>>m>>p;
FOR(i,1,n)fa[i]=i;
FOR(i,1,m){
ll a,b;
cin>>a>>b;
connect(a,b);
}
FOR(i,1,p){
ll a,b;
cin>>a>>b;
if(find(a)==find(b)){
cout<<"Yes"<<endl;
}
else cout<<"No"<<endl;
}
}
Grape_DFS
const int maxn=1000010;
const int num=10;
priority_queue< pair<ll,ll> >q;
int head[maxn],nxt[maxn*num],to[maxn*num],tot,v[maxn];
int val[maxn*num];
int dist[maxn];
int a,b;
void add(int u,int v,int k){
to[++tot]=v;
val[tot]=k;
nxt[tot]=head[u];
head[u]=tot;
return;
}
ll ans;
void dfs(ll x,ll sum){
ans=max(sum,ans);
v[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(v[y]) continue;
dfs(y,val[i]+sum);
v[y]=0;
ans=max(sum,ans);
}
}
int main(){
ll n,m;
cin>>n>>m;
FOR(i,1,m){
ll u,v,k;
cin>>u>>v>>k;
add(u,v,k);
add(v,u,k);
}
FOR(i,1,n){
memset(v,0,sizeof(v));
dfs(i,0);
}
cout<<ans;
return 0;
}
Floyd
int a[505];
int d[506][506];
void Floyd(){
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (d[i][k]+d[k][j]<d[i][j]&&p[i]==1&&p[k]==1)
d[i][j]=d[i][k]+d[k][j];
return ;
}
int main(){
return 0;
}
Dijkstra
const int maxn = 1000010;
const int num = 10;
priority_queue<pair<ll, ll>> q;
int head[maxn], nxt[maxn * num], to[maxn * num], tot, v[maxn];
int val[maxn * num];
int dist[maxn];
int a, b;
void add(int u, int v, int k)
{
to[++tot] = v;
val[tot] = k;
nxt[tot] = head[u];
head[u] = tot;
return;
}
void dijkstra()
{
memset(dist, 0x3f, sizeof(dist));
dist[a] = 0;
q.push(mp(-dist[a], a));
while (!q.empty())
{
int x = q.top().second;
if (v[x])
{
q.pop();
continue;
}
x = q.top().second;
q.pop();
v[x] = 1;
for (int i = head[x]; i; i = nxt[i])
{
int y = to[i];
if (v[y])
continue;
if (dist[y] > dist[x] + val[i])
{
dist[y] = dist[x] + val[i];
q.push(mp(-dist[y], y));
}
}
}
return;
}
int main()
{
ll n, m;
cin >> n >> m;
FOR(i, 1, m)
{
ll u, v, k;
cin >> u >> v >> k;
add(u, v, k);
add(v, u, k);
}
dijkstra();
FOR(i, 1, n)
cout << dist[i];
return 0;
}
Bellman-ford
const int MAXN = 100010;
int n,m,s;
struct Edge {
int v;
int c;
};
vector<Edge> edges[MAXN];
int dis[MAXN];
void bellman_ford(){
dis[s] = 0;
FOR(i,1,MAXN-1)
if (i!=s)
dis[i]=0x3f3f3f3f;
FOR(i,1,n){
bool f=0;
FOR(u,1,n)
for (Edge edge:edges[u])
if (dis[edge.v]>dis[u] + edge.c) {
dis[edge.v]=dis[u] + edge.c;
f=true;
}
if(!f)break;
}
}
int main() {
cin>>n>>m>>s;
FOR(i,1,m){
int u,v,c;
cin>>u>>v>>c;
edges[u].push_back({v,c});
}
bellman_ford();
FOR(i,1,n)
printf("%d ",dis[i]);
return 0;
}
SPFA
const int MAXN = 100010;
int n,m,s;
struct Edge{
int v;
int c;
};
vector<Edge> edges[MAXN];
int dis[MAXN];
queue<int> q;
bool in_queue[MAXN];
void spfa(){
dis[s]=0;
FOR(i,1,MAXN-1)
if (i!=s)
dis[i]=0x3f3f3f3f;
q.push(s);
in_queue[s]=1;
while(!q.empty()) {
int u=q.front();
q.pop();
in_queue[u]=false;
for (Edge e:edges[u]) {
int v=e.v;
if (dis[v]>dis[u]+e.c){
dis[v]=dis[u]+e.c;
if (!in_queue[v]) {
q.push(v);
in_queue[v]=1;
}
}
}
}
}
int main() {
cin >>n>>m>>s;
FOR(i,1,m){
int u,v,c;
cin>>u>>v>>c;
edges[u].push_back({v,c});
}
spfa();
FOR(i,1,n)cout<<dis[i]<<" ";
return 0;
}
Prim
const int maxn = 400500;
struct edge
{
int to, nxt, val;
} e[maxn];
int head[maxn], cnt, dis[maxn], tot, ans;
bool vis[maxn];
void add(int u, int v, int k)
{
e[++cnt].nxt = head[u];
e[cnt].to = v;
e[cnt].val = k;
head[u] = cnt;
}
struct node
{
int pos, dis;
friend bool operator<(node a, node b)
{
return a.dis > b.dis;
}
}tmp;
priority_queue<node>q;
int n, m;
void prim(){
FOR(i,1,n){
dis[i]=2147483647;
}
dis[1]=0;
tmp.dis=0;
tmp.pos=1;
q.push(tmp);
while(!q.empty()){
tmp=q.top();q.pop();
int u=tmp.pos,t=tmp.dis;
if(vis[u])continue;
tot++;
vis[u]=1;
ans+=dis[u];
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
int w=e[i].val;
if(dis[v]>w){
tmp.dis=dis[v]=w;
tmp.pos=v;
q.push(tmp);
}
}
}
}
int main()
{
cin >> n >> m;
FOR(i, 1, m)
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
prim();
if (tot == n)
{
cout << ans;
}
else
cout << "orz";
}
Kruskal
const int maxn=1000010;
int fa[maxn],n,k,m;
struct node{
int u,v;
ll w;
}c[20*maxn];
bool cmp(node a,node b){
return a.w<b.w;
}
int find(int x) {
if(x!=fa[x])
fa[x]=find(fa[x]);
return fa[x];
}
void connect(int x, int y){
int c=find(x);
int d=find(y);
fa[c]=d;
}
int main(){
ll n,m;
cin>>n>>m;
FOR(i,1,m)fa[i]=i;
FOR(i,1,m){
ll u,v,k;
cin>>c[i].u>>c[i].v>>c[i].w;
}
sort(c+1,c+n+1,cmp);
ll ans=0,cnt=0;
FOR(i,1,n){
if(find(c[i].u)!=find(c[i].v)){
int eu=find(c[i].u), ev=find(c[i].v);
if(eu==ev){
continue;
}
ans+=c[i].w;
fa[ev]=eu;
if(++cnt==n-1)
{
break;
}
}
}
cout<<ans;
return 0;
}
Segment Tree
const int maxn=1000006;
ll a[maxn],w[maxn*4];
void pushup(int u){
w[u]=w[u*2]+w[u*2+1];
return ;
}
void build(int u,int L,int R){
if (L==R){
w[u]=a[L];
return ;
}
int M=(L+R)/2;
build(u*2,L,M);
build(u*2+1,M+1,R);
pushup(u);
}
ll query1(int u,int L,int R,int p){
if(L==R){
return w[u];
}
else {
int M=(L+R)/2;
if(M>=p){
return query1(u*2,L,M,p);
}
else return query1(u*2+1,M+1,R,p);
}
}
void update1(int u,int L,int R,int p,ll x){
if(L==R){
w[u]=x;
return;
}
else {
int M=(L+R)/2;
if(M>=p){
update1(u*2,L,M,p,x);
}
else update1(u*2+1,M+1,R,p,x);
pushup(u);
}
}
bool InRange(int L,int R,int l,int r){
return (l<=L) && (R<=r);
}
bool OutofRange(int L,int R,int l,int r){
return (L>r) || (R<l);
}
ll lzy[maxn*4];
void maketag(int u,int len,ll x){
lzy[u]+=x;
w[u]+=len*x;
return ;
}
void pushdown(int u,int L,int R){
int M=(L+R)/2;
maketag(u*2,M-L+1,lzy[u]);
maketag(u*2+1,R-M,lzy[u]);
lzy[u]=0;
}
ll query(int u,int L,int R,int l,int r){
if(InRange(L,R,l,r)){
return w[u];
}
else if(!OutofRange(L,R,l,r)){
int M=(L+R)/2;
pushdown(u,L,R);
return query(u*2,L,M,l,r) + query(u*2+1,M+1,R,l,r);
}
else return 0;
}
void update(int u,int L,int R,int l,int r,ll x){
if(InRange(L,R,l,r)){
maketag(u,R-L+1,x);
}
else if(!OutofRange(L,R,l,r)){
int M=(L+R)/2;
pushdown(u,L,R);
update(u*2,L,M,l,r,x);
update(u*2+1,M+1,R,l,r,x);
pushup(u);
}
}
int main(){
int n,m;
cin>>n>>m;
FOR(i,1,n){
cin>>a[i];
}
build(1,1,n);
FOR(t,1,m){
int op,x,y;
ll k;
cin>>op;
if(op==1){
cin>>x>>y>>k;
update(1,1,n,x,y,k);
}
else {
cin>>x>>y;
cout<<query(1,1,n,x,y)<<endl;
}
}
return 0;
}
BIT
const int maxn = 500010;
int n, m;
int a[maxn], c[maxn];
int lowbit(int x)
{
return x & (-x);
}
int sum(int x)
{
int res = 0;
for (int i = x; i; i -= lowbit(i))
res += c[i];
return res;
}
void add(int x, int y)
{
for (int i = x; i <= n; i += lowbit(i))
c[i] += y;
}
int main()
{
cin >> n >> m;
FOR(i, 1, n)
{
cin >> a[i];
add(i, a[i]);
}
while (m--)
{
int op, x, y;
cin >> op >> x >> y;
if (op == 1)
{
add(x, y);
}
else
cout << sum(y) - sum(x - 1) << endl;
}
return 0;
}
珂朵莉树
#include <bits/stdc++.h>
using namespace std;
struct Node {
ll l , r;
mutable ll v;
Node(const ll &il , const ll &ir , const ll &iv) : l(il) , r(ir) , v(iv) { }
inline bool operator < (const Node &o) const {
return l < o.l;
}
};
typedef set<Node>::iterator sit;
set<Node> ODT;
sit Split(ll Pos) {
sit it = ODT.lower_bound(Node(Pos , 0 , 0));
if(it != ODT.end() && it -> l == Pos) return it;
it--;
ll l = it -> l;
ll r = it -> r;
ll v = it -> v;
ODT.erase(it);
ODT.insert(Node(l , Pos - 1 , v));
return ODT.insert(Node(Pos , r , v)).first;
}
void Assign(ll l , ll r , ll v) {
sit itr = Split(r + 1);
sit itl = Split(l);
ODT.erase(itl , itr);
ODT.insert(Node(l , r , v));
}
void Add(ll l , ll r , ll v) {
sit itr = Split(r + 1);
sit itl = Split(l);
for(sit it = itl ; it != itr; it++) {
it -> v += v;
}
}
ll Rank(ll l , ll r , ll k) {
sit itr = Split(r + 1);
sit itl = Split(l);
vector<pair<ll , ll> > v;
v.clear();
for(sit it = itl; it != itr; it++) {
v.push_back(make_pair(it -> v , it -> r - it -> l + 1));
}
sort(v.begin() , v.end());
ll i;
for(i = 0; i < v.size(); i++) {
if(v[i].second < k) {
k -= v[i].second;
}
else {
break;
}
}
return v[i].first;
}
ll BinPower(ll x , ll y , ll p) {
ll res = 1;
x %= p;
while(y) {
if(y & 1) res = res * x % p;
x = x * x % p;
y >>= 1;
}
return res;
}
ll Cal_p(ll l , ll r , const ll x , const ll y) {
sit itr = Split(r + 1);
sit itl = Split(l);
ll Ans = 0;
for(sit it = itl; it != itr; it++) {
Ans = (Ans + BinPower(it -> v , x , y) * (it -> r - it -> l + 1) % y) % y;
}
return Ans;
}
红黑树
#include <iostream>
using namespace std;
template<class T>
class RB_Tree {
private:
static const bool RED = 0;
static const bool BLACK = 1;
struct Node { //红黑树节点
T Value;
int Size;
bool Color;
Node* LeftTree, * RightTree, * Parent;
Node() : Value(0), Size(0) , Color(RED), LeftTree(NULL), RightTree(NULL), Parent(NULL) { }
Node* GrandParent() {
if (Parent == NULL)
return NULL;
else
return Parent->Parent;
}
Node* Uncle() {
if (GrandParent() == NULL)
return NULL;
if (Parent == GrandParent()->RightTree)
return GrandParent()->LeftTree;
else
return GrandParent()->RightTree;
}
Node* Sibling() {
if (Parent->LeftTree == this)
return Parent->RightTree;
else
return Parent->LeftTree;
}
};
void Rotate_Right(Node* p) { //右旋
Node* gp = p->GrandParent();
Node* fa = p->Parent;
Node* y = p->RightTree;
fa->LeftTree = y;
if (y != NIL)
y->Parent = fa;
p->RightTree = fa;
fa->Parent = p;
if (root == fa)
root = p;
p->Parent = gp;
fa->Size -= 1 + p->LeftTree->Size;
p->Size++;
if (gp != NULL) {
if (gp->LeftTree == fa)
gp->LeftTree = p;
else
gp->RightTree = p;
}
}
void Rotate_Left(Node* p) { //左旋
if (p->Parent == NULL) {
root = p;
return;
}
Node* gp = p->GrandParent();
Node* fa = p->Parent;
Node* y = p->LeftTree;
fa->RightTree = y;
if (y != NIL)
y->Parent = fa;
p->LeftTree = fa;
fa->Parent = p;
if (root == fa)
root = p;
p->Parent = gp;
fa->Size -= 1 + p->RightTree->Size;
p->Size++;
if (gp != NULL) {
if (gp->LeftTree == fa)
gp->LeftTree = p;
else
gp->RightTree = p;
}
}
void Inorder(Node* p) { //中根遍历
if (p == NIL)
return;
if (p->LeftTree)
inorder(p->LeftTree);
cout << p->Value << " ";
if (p->rightTree)
inorder(p->RightTree);
}
string OutPutColor(bool color) { //输出颜色
return color ? "BLACK" : "RED";
}
Node* GetSmallestChild(Node* p) { //最小键
if (p->LeftTree == NIL)
return p;
return GetSmallestChild(p->LeftTree);
}
Node* GetBiggestChild(Node* p) { //最大键
if (p->RightTree == NIL)
return p;
return GetSmallestChild(p->RightTree);
}
bool Delete_Child(Node* p, T Date) { //删除
if (p->Value > Date) {
if (p->LeftTree == NIL)
return false;
return Delete_Child(p->LeftTree, Date);
}
else if (p->Value < Date) {
if (p->RightTree == NIL)
return false;
return Delete_Child(p->RightTree, Date);
}
else if (p->Value == Date) {
if (p->RightTree == NIL) {
p->Parent->Size--;
Delete_One_Child(p);
return true;
}
Node* smallest = GetSmallestChild(p->RightTree);
swap(p->Value, smallest->Value);
smallest->Parent->Size--;
Delete_One_Child(smallest);
return true;
}
else {
return false;
}
p->Size = p->LeftTree->Size + p->RightTree->Size + 1;
}
void Delete_One_Child(Node* p) {
Node* child = p->LeftTree == NIL ? p->RightTree : p->LeftTree;
if (p->Parent == NULL && p->LeftTree == NIL && p->RightTree == NIL) {
p = NULL;
root = p;
return;
}
if (p->Parent == NULL) {
delete p;
child->Parent = NULL;
root = child;
root->Color = BLACK;
return;
}
if (p->Parent->LeftTree == p)
p->Parent->LeftTree = child;
else
p->Parent->RightTree = child;
child->Parent = p->Parent;
if (p->Color == BLACK) {
if (child->Color == RED)
child->Color = BLACK;
else
Delete_Case(child);
}
delete p;
}
void Delete_Case(Node* p) {
if (p->Parent == NULL) {
p->Color = BLACK;
return;
}
if (p->Sibling()->Color == RED) {
p->Parent->Color = RED;
p->Sibling()->Color = BLACK;
if (p == p->Parent->LeftTree)
Rotate_Left(p->Parent);
else
Rotate_Right(p->Parent);
}
if (p->Parent->Color == BLACK && p->Sibling()->Color == BLACK && p->Sibling()->LeftTree->Color == BLACK && p->Sibling()->RightTree->Color == BLACK) {
p->Sibling()->Color = RED;
Delete_Case(p->Parent);
}
else if (p->Parent->Color == RED && p->Sibling()->Color == BLACK && p->Sibling()->LeftTree->Color == BLACK && p->Sibling()->RightTree->Color == BLACK) {
p->Sibling()->Color = RED;
p->Parent->Color = BLACK;
}
else {
if (p->Sibling()->Color == BLACK) {
if (p == p->Parent->LeftTree && p->Sibling()->LeftTree->Color == RED && p->Sibling()->RightTree->Color == BLACK) {
p->Sibling()->Color = RED;
p->Sibling()->LeftTree->Color = BLACK;
Rotate_Right(p->Sibling()->LeftTree);
}
else if (p == p->Parent->RightTree && p->Sibling()->LeftTree->Color == BLACK && p->Sibling()->RightTree->Color == RED) {
p->Sibling()->Color = RED;
p->Sibling()->RightTree->Color = BLACK;
Rotate_Left(p->Sibling()->RightTree);
}
}
p->Sibling()->Color = p->Parent->Color;
p->Parent->Color = BLACK;
if (p == p->Parent->LeftTree) {
p->Sibling()->RightTree->Color = BLACK;
Rotate_Left(p->Sibling());
}
else {
p->Sibling()->LeftTree->Color = BLACK;
Rotate_Right(p->Sibling());
}
}
}
void Insert(Node* p, T Data) { //插入
if (p->Value >= Data) {
if (p->LeftTree != NIL)
Insert(p->LeftTree, Data);
else {
Node* tmp = new Node();
tmp->Value = Data;
tmp->LeftTree = tmp->RightTree = NIL;
tmp->Parent = p;
p->LeftTree = tmp;
tmp->Size = 1;
p->Size = p->LeftTree->Size + p->RightTree->Size + 1;
Insert_case(tmp);
}
}
else {
if (p->RightTree != NIL)
Insert(p->RightTree, Data);
else {
Node* tmp = new Node();
tmp->Value = Data;
tmp->LeftTree = tmp->RightTree = NIL;
tmp->Parent = p;
p->RightTree = tmp;
tmp->Size = 1;
p->Size = p->LeftTree->Size + p->RightTree->Size + 1;
Insert_case(tmp);
}
}
}
void Insert_case(Node* p) {
if (p->Parent == NULL) {
root = p;
p->Color = BLACK;
return;
}
if (p->Parent->Color == RED) {
if (p->Uncle()->Color == RED) {
p->Parent->Color = p->Uncle()->Color = BLACK;
p->GrandParent()->Color = RED;
Insert_case(p->GrandParent());
}
else {
if (p->Parent->RightTree == p && p->GrandParent()->LeftTree == p->Parent) {
Rotate_Left(p);
p->Color = BLACK;
p->Parent->Color = RED;
Rotate_Right(p);
}
else if (p->Parent->LeftTree == p && p->GrandParent()->RightTree == p->Parent) {
Rotate_Right(p);
p->Color = BLACK;
p->Parent->Color = RED;
Rotate_Left(p);
}
else if (p->Parent->LeftTree == p && p->GrandParent()->LeftTree == p->Parent) {
p->Parent->Color = BLACK;
p->GrandParent()->Color = RED;
Rotate_Right(p->Parent);
}
else if (p->Parent->RightTree == p && p->GrandParent()->RightTree == p->Parent) {
p->Parent->Color = BLACK;
p->GrandParent()->Color = RED;
Rotate_Left(p->Parent);
}
}
}
}
bool Find(Node* p, T Date) {
if (p->Value > Date) {
if (p->LeftTree == NIL)
return false;
return Find(p->LeftTree, Date);
}
else if (p->Value == Date) {
return true;
}
else if (p->Value < Date) {
if (p->RightTree == NIL)
return false;
return Find(p->RightTree, Date);
}
else {
return false;
}
}
void Delete_Tree(Node* p) { //删除红黑树
if (!p || p == NIL) {
return;
}
Delete_Tree(p->LeftTree);
Delete_Tree(p->RightTree);
delete p;
}
public:
RB_Tree() {
NIL = new Node;
NIL->Color = BLACK;
root = NULL;
}
~RB_Tree() {
if (root)
Delete_Tree(root);
delete NIL;
}
void Inorder() { //中根遍历
if (root == NULL)
return;
Inorder(root);
cout << endl;
}
void Insert(T x) { //插入
if (root == NULL) {
root = new Node();
root->Color = BLACK;
root->LeftTree = root->RightTree = NIL;
root->Size = 1;
root->Value = x;
}
else {
Insert(root, x);
}
}
bool Delete(T data) { //删除
return Delete_Child(root, data);
}
int Size() {
if (root == NULL)
return 0;
return root->Size;
}
bool Find(T Date) {
return Find(root, Date);
}
private:
Node* root, * NIL;
};
RB_Tree<int> test;
int main() {
return 0;
}
自顶向下Splay
#include <bits/stdc++.h>
using namespace std;
#define ls son[0]
#define rs son[1]
const int maxn = 1e5 + 5;
template <class _Tp> class splay_tree {
private:
struct node;
typedef node* pos;
node buf[maxn];
int buf_cnt, fix_cnt;
pos need_fix[maxn];
struct node {
_Tp val;
int cnt, size;
pos son[2]; // 0ls, 1rs
node() { cnt = size = 0; val = 0; ls = rs = NULL; }
};
inline pos new_node(_Tp val, int cnt) {
pos res = buf + (++buf_cnt);
res -> ls = res -> rs = buf;
res -> val = val; res -> cnt = res -> size = cnt;
return res;
}
pos root;
public:
splay_tree() { buf -> ls = buf -> rs = buf; buf -> cnt = buf -> size = 0; root = buf; }
void insert(_Tp val) { root = __insert(val, 1, root); }
void insert(_Tp val, int cnt) { root = __insert(val, cnt, root); }
void remove(_Tp val) { root = __remove(val, root); }
void print() { __print(root); }
void debug() {
putchar('\n');
printf("root: %d\n", root - buf);
for (int i = 0; i <= buf_cnt; i++) {
printf("node#%d val: %d cnt: %d size: %d ls: %d rs: %d\n", i, buf[i].val, buf[i].cnt, buf[i].size, buf[i].ls - buf, buf[i].rs - buf);
}
putchar('\n');
}
inline int rank(_Tp val) {
root = splay_val(val, root);
return rank_min(root);
}
inline _Tp kth(int k) {
root = splay_rank(k, root);
return root -> val;
}
_Tp pre(_Tp val) {
pos t = root;
_Tp ans;
while (t != buf) {
if (t -> val < val) {
ans = t -> val;
t = t -> rs;
}
else t = t -> ls;
}
return ans;
}
_Tp nxt(_Tp val) {
pos t = root;
_Tp ans;
while (t != buf) {
if (t -> val > val) {
ans = t -> val;
t = t -> ls;
}
else t = t -> rs;
}
return ans;
}
private:
inline void fix_up(pos x) { x -> size = x -> ls -> size + x -> rs -> size + x -> cnt; }
inline pos rotate(pos x, int with) {
pos y = x -> son[with];
x -> son[with] = y -> son[with ^ 1]; y -> son[with ^ 1] = x;
fix_up(x); fix_up(y);
return y;
}
pos splay_val(_Tp val, pos t) {
node header; header.ls = header.rs = buf;
pos tmp[2] = {&header, &header}; // 0ls_max, 1rs_min
fix_cnt = 0;
while (t -> val != val) {
int f1 = (val > t -> val); // 0ls, 1rs
if (t -> son[f1] == buf) break;
if (t -> son[f1] -> val != val) {
int f2 = (val > t -> son[f1] -> val); // 0ls, 1rs
if (f1 == f2) t = rotate(t, f1);
if (t -> son[f1] == buf) break;
}
tmp[f1 ^ 1] -> son[f1] = t; tmp[f1 ^ 1] = t;
need_fix[++fix_cnt] = t;
t = t -> son[f1];
}
tmp[0] -> rs = t -> ls; tmp[1] -> ls = t -> rs;
t -> ls = header.rs; t -> rs = header.ls;
for (int i = fix_cnt; i >= 1; i--) fix_up(need_fix[i]);
fix_up(t);
return t;
}
inline int rank_min(pos t) { return t -> ls -> size + 1; }
inline int rank_max(pos t) { return t -> ls -> size + t -> cnt; }
pos splay_rank(int k, pos t) {
node header; header.ls = header.rs = buf;
pos tmp[2] = {&header, &header}; // 0ls_max, 1rs_min
fix_cnt = 0;
while (rank_min(t) > k || rank_max(t) < k) {
// printf("#%d %d %d\n", t - buf, rank_min(t), rank_max(t));
int f1 = (rank_max(t) < k); // 0ls, 1rs
if (f1 == 1) k -= rank_max(t);
// printf("f1: %d\n", f1);
if (t -> son[f1] == buf) break;
if (rank_min(t -> son[f1]) > k || rank_max(t -> son[f1]) < k) {
int f2 = (rank_max(t -> son[f1]) < k); // 0ls, 1rs
// printf("f2: %d\n", f2);
if (f1 == f2) {
if (f2 == 1) k -= rank_max(t -> son[f1]);
t = rotate(t, f1);
}
if (t -> son[f1] == buf) break;
}
tmp[f1 ^ 1] -> son[f1] = t; tmp[f1 ^ 1] = t;
need_fix[++fix_cnt] = t;
t = t -> son[f1];
// debug();
}
tmp[0] -> rs = t -> ls; tmp[1] -> ls = t -> rs;
t -> ls = header.rs; t -> rs = header.ls;
for (int i = fix_cnt; i >= 1; i--) fix_up(need_fix[i]);
fix_up(t);
return t;
}
pos __insert(_Tp val, int cnt, pos t) {
pos p = new_node(val, cnt);
if (t == buf) t = p;
else {
t = splay_val(val, t);
if (t -> val == val) {
t -> cnt++; t -> size++;
buf_cnt--;
return t;
}
int f = (val > t -> val); // 0ls, 1rs
p -> son[f] = t -> son[f]; p -> son[f ^ 1] = t; t -> son[f] = buf;
fix_up(t); t = p; fix_up(t);
}
return t;
}
pos __remove(_Tp val, pos t) {
if (t != buf) {
t = splay_val(val, t);
if (val == t -> val) {
t -> size--; t -> cnt--;
if (t -> cnt == 0) {
pos p;
if (t -> ls == buf) p = t -> rs;
else {
p = t -> ls;
p = splay_val(val, p);
p -> rs = t -> rs;
fix_up(p);
}
t -> ls = t -> rs = buf;
t = p;
}
}
}
return t;
}
void __print(pos t) {
if (t == buf) return;
__print(t -> ls);
for (int i = 1; i <= t -> cnt; i++) printf("%d ", t -> val);
__print(t -> rs);
}
};

浙公网安备 33010602011771号