【題目描述】
風見幽香非常喜歡玩乙個叫做 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 #include2view codeconst
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 }
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,每朵花初始高度依次如圖所標。首先給第一朵花澆水,...