題目描述
某校大門外長度為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...