紅綠 線段樹分治, 並查集

2021-09-28 02:00:15 字數 2795 閱讀 1731

對 [ 1,

q_to

t][1, q\_tot]

[1,q_t

ot] 進行線段樹分治, 將每個 綠綠 的 影響區間分為 log⁡q

_tot

\log q\_tot

logq_t

ot個區間散布在線段樹節點中,

其中 qto

tq_tot

qt​o

t 為詢問的總數 .

然後對線段樹dfs

dfsdf

s, 合併祖先鏈的和當前節點的綠綠集合 (使用類似歸併排序的方法),

由於代價只與最大生氣值有關, 所以按生氣值從小到大排序, 從後往前加入並查集, 直到有 敵對紅紅 不得不在乙個集合裡,

這時儲存當前節點貢獻, 將陣列截止到不合法的位置往下遞迴 (此時沒有遍歷到的 綠綠 已無法對答案造成貢獻) .

到根節點處統計答案, 時間複雜度 o(n

2log⁡n

)o(n^2 \log n)

o(n2

logn

)

並查集維護方法詳見 這道題 .

#include

#define reg register

#define pb push_back

intread()

while

(isdigit

(c)) s = s*

10+ c-

'0', c =

getchar()

;return s * flag;

}const

int maxn =

2000005

;int n;

int m;

int q_;

int q_cnt;

int f[maxn]

;int ans[maxn]

;int match[maxn]

;char smp[5]

;struct grn a[maxn]

;bool

cmp(grn x, grn y)

std::vector b[maxn <<2]

, p[maxn <<2]

, tmp;

struct node t[maxn <<2]

;int

find

(int x)

void

build

(int k,

int l,

int r)

void

merge

(int a,

int b)

void

insert

(int k,

const grn &aim)

void

dfs(

int k)

while

(t2 < len_2) tmp.

pb(b[k]

[t2 ++])

;while

(t1 < len_1) tmp.

pb(p[k>>1]

[t1 ++])

;for

(reg int i =

1; i <=

2*n+

1; i ++

) f[i]

= i, match[i]=0

;for

(reg int i = tmp.

size()

-1; i >=

0; i --)}

/* for(reg int i = tmp.size()-1; i >= 0; i --)

if(!match[a]) match[a] = b;

else merge(match[a], b);

if(!match[b]) match[b] = a;

else merge(match[b], a);

}*/if

(l == r)

return ans[l]

= res,

void()

; std::

reverse

(p[k]

.begin()

, p[k]

.end()

);dfs(k<<1)

,dfs

(k<<1|

1);}

intmain()

for(reg int i =

1; i <= q_; i ++

)else q_cnt ++;}

build(1

,1, q_cnt)

; std::

sort

(a+1

, a+m+

1, cmp)

;for

(reg int i =

1; i <= m; i ++

)dfs(1

);for(reg int i =

1; i <= q_cnt; i ++

)printf

("%d\n"

, ans[i]);

return0;

}

線段樹 樹狀陣列 並查集

利用線段樹十分方便的處理區間,線段樹是一棵完美的二叉樹,樹上的每乙個節點都維護乙個區間,根維護的是整個區間,線段樹通常用來計算區間內資料的和或者是修改某處的值。對區間的操作可以再o logn 的時間內完成。下面我們通過 實現線段樹的構建,修改,區間求和。include include 線段樹 def...

poj1456 並查集or線段樹

本來做並查集專題看到的題目,但是卻是用線段樹a掉的,感覺這題用線段樹做挺水的。先將物品按價值降序排序,然後依次查詢,每個物品的最後期限,就相當於給了線段樹查詢範圍,在1 d範圍內找還有沒有空餘的點,有的話則占用,更新線段樹,單點更新,感覺比較簡單。如果用並查集的話,題目將用過的天作為乙個集合,排序之...

LA 4730 Kingdom 線段樹 並查集

la 4730 題意 有n個帶座標的城市,和m個操作,每次操作 road a b,連線a,b城市成為乙個州 或者 line c,查詢y c的水平線和多少個州相交以及這些州一共包含多少個城市。思路 可以把每個城市的x座標忽略,把縱座標看做線段樹的區間,乙個點就相當於更新區間 y,y 一條線就相當於更新...