線段樹解決偏序問題

2021-10-04 20:08:39 字數 3432 閱讀 9445

1.e - buses and people

題意:給定 n 個三元組 (a,b,c),現有 m 個詢問,每個詢問給定乙個三元組 (a』,b』,c』),求滿足 a<=a』, b』<=b, c』<=c 的最小 c 對應的元組編號。

思路:首先肯定離線排序處理,我們按照a排序,那麼它之前的元組肯定都滿足第乙個條件。

它之前的元組滿足b』<=b,最小的c的下標怎麼處理呢?題目說每個c都是不同的,我們不妨在c上建立線段樹,維護最大值b和下標,查詢的時候直接查詢大於c的區間。

查詢的時候記得剪枝,因為線段樹維護區間最大值的時候就是為了省時間。

#include

using

namespace std;

const

int n =

2e5+5;

typedef

long

long ll;

int n, q, m, pos, x, r, val, cnt =

0, op;

int ans[n]

, mp[n]

;struct node

} a[n]

;vector<

int>g[n]

;struct seg_tree

void

build

(int i,

int l,

int r)

void

update

(int i,

int l,

int r,

int pos,

int _val,

int _id)

int mid =

(l + r)/2

;if(pos <= mid)

update

(i *

2, l, mid, pos, _val, _id)

;else

update

(i *2+

1, mid +

1, r, pos, _val, _id)

;pushup

(i);

}int

query

(int i,

int l,

int r,

int ql,

int qr,

int _val)

if(l == r)

int ans =-1

, mid =

(l + r)/2

;if(ql <= mid)

if(qr > mid)

return ans;

}} seg;

intmain()

sort

(a +

1, a + n + m +1)

;sort

(mp +

1, mp + cnt +1)

; cnt =

unique

(mp +

1, mp + cnt +1)

- mp -1;

seg.

build(1

,1, cnt)

;for

(int i =

1; i <= n + m; i++

)else

ans[a[i]

.id - n]

= seg.

query(1

,1, cnt, pos, cnt, a[i]

.r);

}for

(int i =

1; i <= m; i++

)printf

("%d "

, ans[i]);

}

2.d. points

題意給你乙個笛卡爾座標系,現在要支援三種操作,第一種操作是新增乙個點(x,y),第二種操作是刪除乙個點(x,y), 第三種操作是查詢嚴格在點(x,y)右上角的點中,橫座標最小的點,如果有多個點,選擇縱座標最小的那個。

#include

using

namespace std;

const

int n =

2e5+5;

typedef

long

long ll;

int n, q, m, pos, x, r, val, cnt =

0, op;

int ans[n]

, b[n]

, c[n]

;struct node a[n]

;map<

int,

int>mp;

struct seg_tree

void

build

(int i,

int l,

int r)

int mid =

(l + r)/2

;build

(i *

2, l, mid)

;build

(i *2+

1, mid +

1, r);}

void

update

(int i,

int l,

int r,

int pos,

int _val,

int flag)

int mid =

(l + r)/2

;if(pos <= mid)

update

(i *

2, l, mid, pos, _val, flag)

;else

update

(i *2+

1, mid +

1, r, pos, _val, flag)

;pushup

(i);

}int

query

(int i,

int l,

int r,

int ql,

int qr,

int _val)

if(l == r)

int mid =

(l + r)/2

, ans =-1

;if(ql <= mid)

if(qr > mid)

return-1

;}} seg;

intmain()

sort

(b +

1, b + n +1)

;int res =

unique

(b +

1, b + n +1)

- b -1;

for(

int i =

1; i <= n; i++

) seg.

build(1

,1, res)

;for

(int i =

1; i <= n; i++)}

}}

Assign the task(dfs序 線段樹)

hdoj 3974 題意 有一家公司有n個員工 從1到n 公司裡每個員工都有乙個直接的老闆 除了整個公司的領導 如果你是某人的直接老闆,那個人就是你的下屬,他的所有下屬也都是你的下屬。如果你是沒有人的老闆,那麼你就沒有下屬,沒有直接老闆的員工就是整個公司的領導,也就是說n個員工構成了一棵樹。公司通常...

Assign the task(dfs序 線段樹)

題目傳送門 assign the task 給你一棵樹,共n個結點,每個結點具有乙個顏色,可以對結點進行染色和查詢 共n 1條邊,分n 1行分別包含兩個整數u和v,表示v是u的父節點 然後有m次操作 若為染色操作則輸入 t x k 若為查詢操作則輸入 c x 首先可以用dfs序將無根樹區間化,即可以...

dfs序 線段樹

傳送門 現有一棵樹,有以下操作 1.節點x及其所有子孫顏色都變更為k。2.要求你回答節點x的顏色。初始所有點都沒有染色。input 第一行乙個整數t t 10 表示樣例組數。對於每個測試樣例 第一行乙個整數n n 5e4 表示樹的節點個數。接下來n行,每行兩個整數u,v 1 u,v n 表示樹中u的...