BZOJ5005 桌球遊戲 線段樹 並查集

2022-05-20 07:33:25 字數 2275 閱讀 1587

如果乙個區間的端點在區間內,則這個區間可以走到那個區間,詢問乙個區間能否到另乙個區間。

首先我們立馬想到了:如果兩個區間嚴格有交集,那麼這兩個區間所能到達的區間集合是一樣的。那麼如果兩個區間嚴格有交集的話我們就可以把它們合併起來,這裡運用並查集。

這樣處理完之後,剩下的區間只有兩種情況:包含或者相離。那麼查詢的時候顯然只要判斷兩個區間指向的大區間的情況即可。

最後,由於這題區間端點權比較大,所以要先離散化。

1 #include2 #include

3 #include4 #include5 #include6 #include7 #include8 #include9

using

namespace

std;

1011

const

int one=100005*8;12

const

int inf=1e9+1;13

14int

n;15

intnum,cnt;

1617 vector node[one];

1819

struct

power

20a[one],interval[one];

2324

intq[one],li_num;

25struct

lisan

26li[one];

2930

intget

()31

4041

namespace

li42

5051

int cmp(const lisan &a,const lisan &b)

52void

lisan()

5363 num=cnt;

6465 cnt=0;66

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

67if(a[i].opt==1

)68 a[i].l=q[++cnt], a[i].r=q[++cnt];

6970}71

}7273int

fat[one];

74int find(int

x)75

7980

namespace

seg81

93node[i].clear();94}

95if(l==r) return;96

int mid = (l+r)>>1;97

if(l <= mid) delete(i<<1

, l, mid, l);

98else delete(i<<1|1, mid+1

, r, l);99}

100101

void update(int i,int l,int r,int l,int

r)102

109int mid=(l+r)>>1

;110

if(l<=mid) update(i<<1

,l,mid,l,r);

111if(mid+1

<=r) update(i<<1|1,mid+1

,r,l,r);

112}

113}

114115

bool

p_edge(power a,power b)

116120

121int

main()

122130

for(int i=1;i<=num;i++) fat[i]=i;

131132

li::lisan();

133134 cnt=0

;135

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

136144

else

145152

}153 }

view code

bzoj 4515 遊戲 樹鏈剖分 線段樹

先讓我 一發lych大佬點我去看dalao的題解 講的很詳細.這裡糾正乙個地方,lych大佬的式子中有乙個 a d s d x b a d x b a d s 應該是 a d s d x b a d x b a d s 看來是大爺敲式子的時候敲錯了.除去這個就很完美啦 新get了線段樹標記永久化的姿...

bzoj4881 線段遊戲

相當於走出兩條路線,將所有數包含,使得每條路線都是單調增的。為了方便我們加入p 0 0和p n 1 n 1。設f i 表示一條路線 沒有指定是第一條路線 走到了i 1,另一條路線走到了i,滿足條件的方案數。邊界是f 1 1,答案是f n 1 2 兩條路線實際上不可區分但原題中可區分那麼它們可以交換即...

BZOJ 4756 線段樹合併(線段樹)

思路 1.最裸的線段樹合併 2.我們可以觀察到子樹求乙個東西 那我們直接dfs序好了 入隊的時候統計一下有多少比他大的 出的時候統計一下 減一下 搞定 線段樹合併 by siriusren include include include using namespace std const int n...