校門外的樹 珂朵莉樹

2021-10-02 22:03:39 字數 4487 閱讀 7367

題目描述

某校大門外長度為l的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是11公尺。我們可以把馬路看成乙個數軸,馬路的一端在數軸00的位置,另一端在ll的位置;數軸上的每個整數點,即0,1,2,…,l0,1,2,…,l,都種有一棵樹。

由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已知任一區域的起始點和終止點的座標都是整數,區域之間可能有重合的部分。現在要把這些區域中的樹(包括區域端點處的兩棵樹)移走。你的任務是計算將這些樹都移走後,馬路上還有多少棵樹。

輸入格式

第一行有22個整數 l(1 \le l \le 10000)l(1≤l≤10000) 和 m(1 \le m \le 100)m(1≤m≤100),ll代表馬路的長度,mm代表區域的數目,ll和mm之間用乙個空格隔開。

接下來的mm行每行包含22個不同的整數,用乙個空格隔開,表示乙個區域的起始點和終止點的座標。

輸出格式

11個整數,表示馬路上剩餘的樹的數目。

輸入輸出樣例

輸入500 3

150 300

100 200

470 471

輸出298

簡單的模擬過去的**

#include

#include

using

namespace std;

int a,b;

bool flag[

100005];

intmain()

}for

(int i=

0;i<=l;i++

) cout

}

但是做完之後,我發現有更簡潔的演算法,而且有個奇特的名字珂朵莉樹,嘻嘻,耐不住好奇心,就去查了查資料,然後自己總結一下。

改題目使用珂朵莉樹**如下:

#include

#include

#include

#define re register

#define for(i,l,r) for(re int i=l;i<=r;++i)

using

namespace std;

int a[

200001

],i,h1,h2,s=

0,m,l,j;

inline

void

in(re int

&x)while

(c<=

'9'&&c>=

'0')

}inline

void

out(re int a)

intmain()

for(i,

0,l)

if(a[i]==0

)++s;

out(s)

;puts(""

);}

珂朵莉樹的構造**如下:

#include

#include

#include

#include

#include

#define re register

#define for(i,l,r) for(re int i=l;i<=r;++i)

#define it set::iterator

using

namespace std;

int n,m,x,y;

inline

void

in(re int

&x)while

(c<=

'9'&&c>=

'0')

}inline

void

out(re int a)

struct node

bool

operator

<

(const node &o)

const};

set s;

inline it split

(re int pos)

inline

void

assign_val

(re int l,re int r,re int val=0)

inline

intquery

(re int l,re int r)

intmain()

out(

query(0

,n))

;puts(""

);}

珂朵莉樹到底是幹嘛的呢?

使一整段區間內的東西變得一樣,資料隨機。

n 個數, m 次操作 (n,m<=10^5) 。

操作:1.區間加

void

add(

int l,

int r, ll val)

2.區間賦值

3.區間第k小

ll rank

(int l,

int r,

int k)

}

4.求區間冪次和

ll pown

(ll a, ll b, ll mod)

return res;

}ll sum

(int l,

int r,

int ex,

int mod)

暴力找到元素,快速冪,加入答案,結束(記得不要忘乘上集合裡的個數)!!!

資料隨機,時限2s。

構造珂朵莉樹

struct node

bool

operator

<

(const node& o)

const

//過載運算子

};

表示【l,r】這乙個區間中所有的數都是v。

重要的操作------**split

#define it set::iterator  

//太長了

it split

(int pos)

實際很簡單,乙個集合中,有一部分需要修改,而另一部分不需要修改,就把集合拆開,拆成兩部分。(要修改的就修改,不修改的就算了)

珂朵莉樹的推平操作:assign_val

void

assign_val

(int l,

int r, ll val)

要是只有split還不得複雜度**?我們需要assign操作迅速減少set的數量。珂朵莉樹的複雜度是由assign_val保證的。由於資料隨機,有1/4的操作為assign。set的大小快速下降,最終趨於logn ,使得這種看似暴力無比的資料結構複雜度接近mlogn .

完整**:

#include

#define it set::iterator

using

namespace std;

typedef

long

long ll;

const

int mod7 =

1e9+7;

const

int mod9 =

1e9+9;

const

int imax_n =

1e5+7;

struct node

bool

operator

<

(const node& o)

const};

ll pown

(ll a, ll b, ll mod)

return res;

}set s;

it split

(int pos)

void

add(

int l,

int r, ll val)

void

assign_val

(int l,

int r, ll val)

ll ranks

(int l,

int r,

int k)

}ll sum

(int l,

int r,

int ex,

int mod)

int n, m;

ll seed, vmax;

ll rd()

ll a[imax_n]

;int

main()

s.insert

(node

(n+1

, n+1,

0));

int lines =0;

for(

int i =

1; i <= m;

++i)

return0;

}

珂朵莉樹學習筆記

珂朵莉樹是一種基於 set 的暴力資料結構,真的很好懂 因為暴力鴨 又叫 old driver tree 老司機樹 適用於區間賦值,資料隨機.首先來講講它的思想,它把區間 1,n 分成若干個 l i,r i l i,r i 內的數都一樣,為 w i 舉栗子 區間 1,5 的初值為 1 現在只有乙個區...

CodeForces 896C 珂朵莉樹

傳送門 用set搞的比較神奇的樹吧,玄學時間複雜度,簡潔好寫,無聊學了用來水題再好不過了 include include include include include include include include include include include include define x ...

問題B 絕地求生 珂朵莉樹

題目描述 吃雞開局了,你降落的森林中有一條長度為s的小路 編號從1到s 且在小路上時常會起霧,你手上的雷射發射器可以讓霧消散。你肯定你所在位置的視野。若位置x有濃霧,則位置x的視野為0。若從x一直到s或從x一直到1全都沒有濃霧,則視野為inf。其他情況下,位置x的視野定義為max,其中l,r滿足 x...