接水果 fruit 整體二分 掃瞄線

2022-09-01 10:39:14 字數 3724 閱讀 3682

【題目描述】

風見幽香非常喜歡玩乙個叫做 osu! 的遊戲,其中她最喜歡玩的模式就是接水果。由於她已經 dt fc 了 the big black,她覺得這個遊戲太簡單了,於是發明了乙個更加難的版本。

首先有乙個地圖,是一棵由 $n$ 個頂點、$n-1$ 條邊組成的樹(例如圖 $1$ 給出的樹包含 $8$ 個頂點、$7$ 條邊)。這顆樹上有 p 個盤子,每個盤子實際上是一條路徑(例如圖 $1$ 中頂點 $6$ 到頂點 $8$ 的路徑),並且每個盤子還有乙個權值。第 $i$ 個盤子就是頂點 $a_i$ 到頂點 $b_i$ 的路徑(由於是樹,所以從 $a_i$ 到 $b_i$ 的路徑是唯一的),權值為 $c_i$。接下來依次會有 $q$ 個水果掉下來,每個水果本質上也是一條路徑,第 $i$ 個水果是從頂點 $u_i$ 到頂點 $v_i$ 的路徑。

幽香每次需要選擇乙個盤子去接當前的水果:乙個盤子能接住乙個水果,當且僅當盤子的路徑是水果的路徑的子路徑(例如圖 $1$ 中從 $3$ 到 $7$ 的路徑是從 $1$ 到 $8$ 的路徑的子路徑)。這裡規定:從 $a$ 到 $b$ 的路徑與從 $b$ 到 $a$ 的路徑是同一條路徑。當然為了提高難度,對於第 $i$ 個水果,你需要選擇能接住它的所有盤子中,權值第 $k_i$ 小的那個盤子,每個盤子可重複使用(沒有使用次數的上限:乙個盤子接完乙個水果後,後面還可繼續接其他水果,只要它是水果路徑的子路徑)。幽香認為這個遊戲很難,你能輕鬆解決給她看嗎?

【輸入格式】

第一行三個數 $n$ 和 $p$ 和 $q$,表示樹的大小和盤子的個數和水果的個數。 

接下來 $n-1$ 行,每行兩個數 $a$、$b$,表示樹上的 $a$ 和 $b$ 之間有一條邊。樹中頂點按 $1$ 到 $n$ 標號。 接下來 $p$ 行,每行三個數 $a$、$b$、$c$,表示路徑為 $a$ 到 $b$、權值為 $c$ 的盤子,其中 $0 \leq c \leq 10^9, \ a \neq b$。

接下來 $q$ 行,每行三個數 $u$、$v$、$k$,表示路徑為 $u$ 到 $v$ 的水果,其中 $u$ 不等於 $v$,你需要選擇第 $k$ 小的盤子,第 $k$ 小一定存在。

【輸出格式】

對於每個果子,輸出一行表示選擇的盤子的權值。

【樣例輸入】

10 10 10

1 22 3

3 44 5

5 66 7

7 88 9

9 10

3 2 217394434

10 7 13022269

6 7 283254485

6 8 333042360

4 6 442139372

8 3 225045590

10 4 922205209

10 8 808296330

9 2 486331361

4 9 551176338

1 8 5

3 8 3

3 8 4

1 8 3

4 8 1

2 3 1

2 3 1

2 3 1

2 4 1

1 4 1

【樣例輸出】

442139372

333042360

442139372

283254485

283254485

217394434

217394434

217394434

217394434

217394434

【資料範圍與提示】

對於所有資料,$n,p,q \leq 40000$。

考慮乙個盤子 $ u,v $ 能接到的水果的範圍,那麼水果的 $ s,t $ 必須分別屬於盤子兩個的兩個子樹,問題即轉化成 $ s,t $ 屬於的第 $k$ 大的盤子

因為乙個子樹在 dfs 序上是乙個區間,乙個盤子就是兩個區間的包含關係,那麼對映到座標系上盤子就成了乙個矩形,水果就成了乙個點,問題變成覆蓋某乙個點的第 $k$ 大的矩形

考慮如何解決,整體二分矩形,判斷覆蓋個數是否大於,然後左右遞迴即可

至於判斷,類似掃瞄線的思想,將矩形按一維排序,另一維區間用資料結構(樹狀陣列)維護,單點查詢即可

如果水果 $ u,v $ 的 lca 為 $ u $ 或 $ v $ 時,需要特判一下

時間效率:$ o(n \log^2 n) $

1 #include2

const

int n=8e4+10;3

using

namespace

std;

4int n,m,q,tot,fa[n][18

],dfn[n],tim,last[n],dep[n],ans[n],sum[n],head[n],cnt;

5struct edgee[n<<1];6

struct platepla[n];

7struct nodeeve[n];

8struct fruitfru[n],s1[n],s2[n];

9bool cmp(plate a,plate b)

10bool cmp1(node a,node b)

11void add(int s,int t),head[s]=cnt;}

1213

class

bit20

int query(int x)

21}t;

2223

void dfs(int

x)31

int jump(int a,int h)

32int lca(int a,int

b)39

40void solve(int l,int r,int st,int

ed)46

int mid=(l+r)>>1,siz=0;47

for (int i=l;i<=mid;i++);

49 eve[++siz]=(node);50}

51for (int i=st;i<=ed;i++) eve[++siz]=(node);

52 sort(eve+1,eve+1+siz,cmp1);

53for (int i=1;i<=siz;i++)

54if (st<=eve[i].id&&eve[i].id<=ed) sum[eve[i].id]=t.query(eve[i].y1);

55else

t.modify(eve[i].y1,eve[i].y2,eve[i].v);

56int a=0,b=0;57

for (int i=st;i<=ed;i++) ;60}

61for (int i=st;i<=st+a-1;i++) fru[i]=s1[i-st+1

];62

for (int i=st+a;i<=ed;i++) fru[i]=s2[i-st-a+1

];63 solve(l,mid,st,st+a-1),solve(mid+1,r,st+a,ed);64}

6566

intmain();

74else;77

if (last[w]1

,n,c};78}

79}80 sort(pla+1,pla+1+tot,cmp);

81for (int i=1,a,b,k;i<=q;i++);85}

86 solve(1,tot,1

,q);

87for (int i=1;i<=q;i++) printf("

%d\n

",ans[i]);

88return0;

89 }

view code

BZOJ4009 接水果(整體二分,掃瞄線)

為什麼這都是許可權題?洛谷真良心 看到這道題,感覺就是主席樹 整體二分之類的東西 因為要求第 k 大 但是,讀完題目之後,我們發現路徑之間的包含關係很不好搞 那麼,我們來畫畫圖 這是第一種情況,lc a不是u,v u,v 分別是乙個盤子的兩端 如果被乙個水果完全覆蓋,那麼,這個水果的兩端分別在u,v...

luogu3242 接水果 整體二分 樹狀陣列

考慮整體二分,問題就變成了每個 水果 路徑有多少個滿足條件 權值 的 盤子 子路徑 考慮乙個盤子 a,b 表示兩端點 不妨設dfn a 1.如果a是b的祖先,則u在 a的在 b,a 鏈上的孩子 這個子樹外,v在b子樹內 2.否則,u在a的子樹內,v在b的子樹內 那麼把乙個水果 a,b 看成是乙個二維...

C Present(二分 掃瞄線)

題意 盆花,澆 次水,每次可使花高度 每次可澆相鄰的 盆,ai 表示 i th盆花 的高度 問 當澆完 次後,最矮的一盆花最高可以使多少?解題思路 二分 掃瞄線,由於高度最高 0 10e5 最小1,然後在 這範圍內二分搜尋。假設此時二分高度為 h 6,每朵花初始高度依次如圖所標。首先給第一朵花澆水,...