笛卡爾樹小結

2022-02-05 07:46:05 字數 3415 閱讀 4303

粗略的學習了一下笛卡爾樹 主要是為了平衡樹打基礎吧 因為關於平衡樹 treap 早忘了 splay 不信任複雜度 然後 我能學一種比較簡單的樹y

笛卡爾樹.這裡以建出小根堆為例。描述區間性質的樹 可以當成二叉搜尋樹不過並不平衡因為每次都是選取當前區間最小值當做為根 然後顯然根據區間的數的排列不同樹的形態也不相同。

所以查詢 插入等操作顯然不適合它 。能做什麼?(我也不知道23333...應該有一定的作用 比如說可以求...

卡爾樹中的乙個點代表的是一段位置,這段位置就是中序遍歷這個點的子樹得到的那段連續區間...

過多我也不會了 也不敢口胡挺簡單的乙個東西。qwq

其實就是這個東西 考慮怎麼構造出來乙個比較簡單的做法是 單調棧 維護整棵樹的右鏈輕鬆完成構造 複雜度o(n)

還有其他的構造方法最簡單的就是遞迴構造法每次暴力掃瞄最小的那個數字 然後qwq.. 複雜度o(n^2)

還有 遞迴構造的時候 考慮線段樹維護區間最小值 於是複雜度降到了 nlogn。。

這裡推薦直接o(n)非常簡單比線段樹不知道高到**去了。

//

#include

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define inf 1000000000

#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)>(y)?(y):(x))

#define us unsigned

#define mod 1000000007

#define db double

using

namespace

std;

const

int maxn=100010

;int

n,rt,top;

ll ans;

inta[maxn];

int st[maxn],s[maxn][2

],f[maxn];

inline

void dfs(int x,int l,int

r)int

main()

rt=st[1];dfs(rt,1,n);printf("

%lld\n

",ans);

}return0;

}

view code

說好了  要寫題的qwq

link:beautiful pair 數點 又見數點 每次遇到數點問題 都是樹狀陣列或者主席數具體的此題我以前模擬賽做過qwq

我用的是單調棧和主席樹(笛卡爾樹什麼的都是浮雲qwq原理差不多 關鍵是暴力掃 可以證明 然後主席樹快速數點即可。

可以證明暴力掃的複雜度是nlog的 所以總複雜度 nlognlogn 所以可以通過本題。

值得一提的是查詢的時候注意邊界 不然會tle 值得一提的是不需要離散 感覺會更慢一點qwq.

//

#include

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define inf 1000000000

#define ll long long

#define db double

#define pb push_back

#define un unsigned

#define l(p) t[p].l

#define r(p) t[p].r

#define sum(p) t[p].sum

using

namespace

std;

char *fs,*ft,buf[1

<<15

];inline

char

getc()

inline

intread()

while(ch>='

0'&&ch<='9')

return x*f;

}const

int maxn=100010

;int

n,cnt;

int minn=inf,maxx,top;

introot[maxn],s[maxn],a[maxn],l[maxn],r[maxn];

struct

wyt[maxn*30

<<1

];ll ans;

inline

void insert(int &p,int last,int l,int r,int

x)

int mid=(l+r)>>1

;

if(x<=mid)insert(l(p),l(last),l,mid,x);

else insert(r(p),r(last),mid+1

,r,x);

sum(p)=sum(l(p))+sum(r(p));

}inline

int ask(int p,int lp,int l,int r,int

w)int

main()

for(int i=1;i<=n;++i)

insert(root[i],root[i-1

],minn,maxx,a[i]);

s[top=1]=0;a[0]=inf+1

;

for(int i=1;i<=n;++i)

s[top=1]=n+1;a[n+1]=inf+1

;

for(int i=n;i;--i)

for(int i=1;i<=n;++i)

}else}}

printf(

"%lld\n

",ans);

return0;

}

view code

pat笛卡爾樹

笛卡爾樹是一種特殊的二叉樹,其結點包含兩個關鍵字k1和k2。首先笛卡爾樹是關於k1的二叉搜尋樹,即結點左子樹的所有k1值都比該結點的k1值小,右子樹則大。其次所有結點的k2關鍵字滿足優先佇列 不妨設為最小堆 的順序要求,即該結點的k2值比其子樹中所有結點的k2值小。給定一棵二叉樹,請判斷該樹是否笛卡...

笛卡爾 關於笛卡爾

陪孩子看書看到笛卡爾,突然想到了笛卡爾積以及cross join等等,無法忽視的數學之美。關於笛卡爾發明座標系還有這樣乙個故事 有一天,笛卡爾 1596 1650,法國哲學家 數學家 物理學家 生病臥床,但他頭腦一直沒有休息,在反覆思考乙個問題 幾何圖形是直觀的,而代數方程則比較抽象,能不能用幾何圖...

笛卡爾樹學習筆記

笛卡爾樹學習筆記 笛卡爾樹是一種二叉樹,每乙個結點由乙個鍵值二元組 k,w 構成。要求 k 滿足二叉搜尋樹的性質,而 w 滿足堆的性質。乙個有趣的事實是,如果笛卡爾樹的 k,w 鍵值確定,且 k 互不相同,w 互不相同,那麼這個笛卡爾樹的結構是唯一的 在一般情況下,未說明 k 時,我們預設 k 為下...