飄雪聖域 樹狀陣列 二維偏序

2021-09-26 07:35:26 字數 2336 閱讀 2680

首 先要

知道:首先要知道:

首先要知道:

若給定乙個區間 [l,

r][l, r]

[l,r

], 設一條邊的小端點為 u

uu, 大端點為 vvv,

滿足條件 l≤u

andv

≤rl \le u\ and\ v \le r

l≤uand

v≤r 的邊數為 num

numnu

m, 則聯通塊數量為 r−l

+1−n

umr-l+1-num

r−l+1−

num .

現 在的

問題就是

:現在的問題就是:

現在的問題就

是:給出若干區間, 如何去快速地去求出每個區間對應的 num

numnu

m .發現這是個二維偏序問題, 於是

先將所有邊以左端點為下標加入樹狀陣列,

對從大到小排好序的詢問 逐一處理, 不斷地將 v

>

rv > r

v>

r 的區間從樹狀陣列中刪掉,

此時樹狀陣列中的所有區間的 v

vv 全部都是 ≤

r\le r

≤r的, 於是只需要計算出 u≥l

u \geq l

u≥l 的區間個數,

為 t ot

−(u≤

l−1區

間個數)

tot- (u \le l-1區間個數)

tot−(u

≤l−1

區間個數

) , 即 que

ry(n

)−qu

ery(

l−1)

query(n) - query(l-1)

query(

n)−q

uery

(l−1

) .

#include

#define reg register

intread()

while

(isdigit

(c)) s = s*

10+ c-

'0', c =

getchar()

;return s * flag;

}const

int maxn =

200005

;int n;

int q_;

int ans[maxn]

;struct edge e[maxn]

;struct que que[maxn]

;struct bit_tree

intquery

(int k)

} bit_t;

bool

cmp_edge

(edge a, edge b)

bool

cmp_que

(que a, que b)

intmain()

for(reg int i =

1; i <= q_; i ++

) que[i]

.l =

read()

, que[i]

.r =

read()

, que[i]

.id = i;

std::

sort

(que+

1, que+q_+

1, cmp_que)

, std::

sort

(e+1

, e+n, cmp_edge)

;for

(reg int i =

1; i < n; i ++

) bit_t.

add(e[i]

.u,1);

int t =1;

for(reg int i =

1; i <= q_; i ++

)for

(reg int i =

1; i <= q_; i ++

)printf

("%d\n"

, ans[i]);

return0;

}

樹狀陣列 飄雪聖域

沒找到傳送門 這是校內的 題意 給一棵樹,多次詢問編號在l到r中的點組成的連通塊個數 考試的時候一直在想奇怪的做法,用的都是樹上維護的知識 比如已經被某c姓神仙卡掉的虛樹 樹剖 二分 其實這道題根本不需要樹上的知識 首先要知道乙個區間的連通塊個數等於點數 邊數 無重邊自環的情況 然後問題就變成了要求...

poj2481(二維偏序 樹狀陣列)

農夫約翰的牛發現,他的田地裡沿著山脊生長的三葉草 我們可以將其視為一維數字線 特別好。農夫約翰有n頭母牛 我們將母牛的編號從1到n 每位農夫約翰的n頭母牛都有她特別喜歡的三葉草範圍 這些範圍可能重疊 範圍由閉合間隔 s,e 定義。但是有些母牛很強壯,有些卻很弱。給定兩個母牛 母牛i和母牛j,它們最喜...

揹包問題 二維偏序, 樹狀陣列

二維偏序問題,將所 有點 按照 v v 為第一關鍵字,w w 為第二關鍵字從大到小排序,從前往後掃,離散化座標,使用樹狀陣列維護 y y 的字首最大值,記為 max cur max cur對於揹包的限制,將揹包按容量從大到小排序,維護乙個指標從左往右根據物品的容量往右移動,記為 tt,揹包從容量大的...