1. 程式人生 > >無旋treap 文藝平衡樹

無旋treap 文藝平衡樹

    因為需要用到區間修改,所以該用splay(尚未填坑)或者無旋treap(剛剛填上)

     最開始的建樹用到了建笛卡爾樹的方法,把id大於當前點的點不斷出棧,又因為這道題的點是按序入棧的,所以當它無法讓更多點出棧時,他就是棧首的右子樹,而最後一個出棧的點,就是當前點的左子樹。顯然root=zhan[1]。

#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define inf 10000000
using namespace std;
int n,m;
struct treap
{
	treap* ch[2];
	int id,h,lazy,size;
	treap(){size=lazy=h=0;id=rand();ch[1]=ch[0]=NULL;}
	inline void update(){size=ch[0]->size+ch[1]->size+1;}
} *null=new treap(),*root=null,*zhan[100005],*x,*last;
typedef pair<treap*,treap*> D;
inline int read()
{
	int sum=0,f=1;char x=getchar();
	while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
	while(x>='0'&&x<='9'){sum=sum*10+x-'0';x=getchar();}
	return sum*f;
}
inline treap* newtreap(int x)
{
	treap *o=new treap();
	o->size=1;o->h=x;
	o->ch[0]=o->ch[1]=null;
	return o;
}
void push(treap *f)
{
	if(f==null)return;
	if(f->lazy)
	{
		f->lazy^=1;
		if(f->ch[0]!=null)f->ch[0]->lazy^=1;
		if(f->ch[1]!=null)f->ch[1]->lazy^=1;
		swap(f->ch[0],f->ch[1]);
	}
}
D split(treap *f,int k)
{
	if(f==null)return  D(null,null);
	push(f);D y;
	if(f->ch[0]->size>=k)
	    {y=split(f->ch[0],k);f->ch[0]=y.second;f->update();y.second=f;}
	else
	    {y=split(f->ch[1],k-f->ch[0]->size-1);f->ch[1]=y.first;f->update();y.first=f;}    
	return y;
}
treap* merge(treap *a,treap *b)
{
	if(a==null)return b;
	if(b==null)return a;
	push(a);push(b);
	if(a->id<b->id)
	     {a->ch[1]=merge(a->ch[1],b);a->update();return a;}
	else
	     {b->ch[0]=merge(a,b->ch[0]);b->update();return b;}
}
void dfs(treap *x)
{
	if(x==null)return;
	push(x);
	if(x->ch[0]!=null)dfs(x->ch[0]);
	printf("%d ",x->h);
	if(x->ch[1]!=null)dfs(x->ch[1]);
}
int yjn()
{
	 freopen("sph.in","r",stdin);
    freopen("sph.out","w",stdout);
	scanf("%d%d",&n,&m);
	int p=0;
	for(int i=1;i<=n;i++)
	{
		x=newtreap(i);last=null;
		while(p&&zhan[p]->id>x->id)
		{zhan[p]->update();last=zhan[p];zhan[p--]=null;}
		if(p)zhan[p]->ch[1]=x;
		x->ch[0]=last;zhan[++p]=x;
	}
	while(p)zhan[p--]->update();
	root=zhan[1];
	int l,r;
	for(int i=1;i<=m;i++)
	{
		l=read();r=read();
		D x=split(root,r);
		D y=split(x.first,l-1);
		if(y.second!=null)y.second->lazy^=1;
		root=merge(merge(y.first,y.second),x.second);
	}
	dfs(root);
}
int qty=yjn();
int main(){;}

相關推薦

treap 文藝平衡

    因為需要用到區間修改,所以該用splay(尚未填坑)或者無旋treap(剛剛填上)      最開始的建樹用到了建笛卡爾樹的方法,把id大於當前點的點不斷出棧,又因為這道題的點是按序入棧的,所以當它無法讓更多點出棧時,他就是棧首的右子樹,而最後一個出棧的點,就是當前

Luogu 3369 / BZOJ 3224 - 普通平衡 - [Treap]

題目連結: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 https://www.luogu.org/problemnew/show/P3369 Description 您需要寫一種資料結構(可參考題目標題),來維護一些數,其中需要提供以下

洛谷P3391 【模板】文藝平衡(Splay)(FHQ Treap

and fine 背景 clas bad 例如 spa 個數 static 題目背景 這是一道經典的Splay模板題——文藝平衡樹。 題目描述 您需要寫一種數據結構(可參考題目標題),來維護一個有序數列,其中需要提供以下操作:翻轉一個區間,例如

Luogu P3391 【模板】文藝平衡(FHQ-Treap

題意 給出一個長為$n$序列$[1,2,...,n]$,$m$次操作,每次指定一段區間$[l,r]$,將這段區間翻轉,求最終序列 題解 雖然標題是$Splay$,但是我要用$FHQ\ Treap$,考慮先將$[l,r]$這段區間$split$出來($k$即為這段區間) void split(int o

Luogu5055 【模板】可持久化文藝平衡(fhq-treap

  注意下傳標記時也需要新建節點。空間開的儘量大。 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #inclu

bzoj3223 文藝平衡 Splay & Treap

平衡樹做區間翻轉 節點維護siz域用於查詢當前第k個位置上的數,翻轉打標記。 對於splay,翻轉[L,R]只要把第L-1個位置轉到根,第R+1個位置轉到root->R的位置,對root->R->L打翻轉標記。 對於合併式treap,翻轉

Luogu P3391 文藝平衡(Splay or FHQ Treap

namespace 坐標 fine pre || pri rank style git 這道題要求區間反轉。。。好東西。。 對於Splay:把l-1旋到根,把r+1旋到根的右兒子,這樣r+1的左兒子就是整個區間了,然後對這個區間打個tg 註意要插-Inf和Inf到樹裏面

Tyvj 1729 文藝平衡

size memory ear push bmi 次數 eve ret != Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4604 Solved: 2691[Submit][Status][Discuss] Descr

【bzoj3223】文藝平衡

dfs pri color hup getc size def name val #include<bits/stdc++.h> #define N 300005 #define rat 4 using namespace std; struct Node{

P3391 文藝平衡

mar new ostream 例如 class static main names include hh 題目描述 您需要寫一種數據結構(可參考題目標題),來維護一個有序數列,其中需要提供以下操作:翻轉一個區間,例如原有序序列是5 4 3 2 1,翻轉區間是[2,4]

【Splay】bzoj3223 Tyvj 1729 文藝平衡

ota ostream max play del || oot tyvj pla #include<cstdio> #include<iostream> #include<cstring> #include<algorithm&g

[BZOJ1503][NOI2004]郁悶的出納員 Treap

就會 lin ++ des 開始 不能 pan min 但是 1503: [NOI2004]郁悶的出納員 Time Limit: 5 Sec Memory Limit: 64 MB Description OIER公司是一家大型專業化軟件公司,有著數以萬計的員工。作為

BZOJ 3223 Tyvj 1729 文藝平衡

color result merge center img hide rip 至少 print 3223: Tyvj 1729 文藝平衡樹 Description 您需要寫一種數據結構(可參考題目標題),來維護一個有序數列,其中需要提供以下操作:

[補檔][Tvyj 1729]文藝平衡

輸出 main cond 數字 () namespace fhq tchar jin 題目 您需要寫一種數據結構(可參考題目標題),來維護一個有序數列,其中需要提供以下操作:翻轉一個區間,例如原有序序列是5 4 3 2 1,翻轉區間是[2,4]的話,結果是5 2 3 4

P3391 【模板】文藝平衡(Splay)

spa 標題 -s gets 需要 () 序列 代碼 輸入 題目背景 這是一道經典的Splay模板題——文藝平衡樹。 題目描述 您需要寫一種數據結構(可參考題目標題),來維護一個有序數列,其中需要提供以下操作:翻轉一個區間,例如原有序序列是5 4 3 2 1,翻轉區間是[2

[BZOJ3223]文藝平衡

light include logs tag pla treap 父親 printf 破壞 以前看著非旋treap的題解寫了一發,沒有真正理解 最近補了一下splay,於是用來練手 因為是區間翻轉,子樹大小不變,所以pushup時兒子對父親沒有影響 因此splay($

[luogu P3391] 文藝平衡

hid clu 模板 搜索樹 open namespace 接下來 getchar() play [luogu P3391] 文藝平衡樹 題目背景 這是一道經典的Splay模板題——文藝平衡樹。 題目描述 您需要寫一種數據結構(可參考題目

洛谷 P3391 【模板】文藝平衡(Splay)

模板 class opera void 直接 曾經 維護 如果 spa 先記一發非旋treap,splay什麽的以後再說 基本就是正常的非旋treap維護序列加上一個flip標記,如果某個節點flip為true表示以它為根的子樹需要一次翻轉。類似線段樹lazytag 每

Treap

return can merge delet oid == find rand() case #include <cstdio> #include <algorithm> #include <cstring> #include

treap板子!

std down cnblogs tdi getch first lib tran logs #include <cstdio> #include <cstring> #include <cmath> #include <algor