zoukankan      html  css  js  c++  java
  • BZOJ 4009: [HNOI2015]接水果

    4009: [HNOI2015]接水果

    Time Limit: 60 Sec  Memory Limit: 512 MB
    Submit: 636  Solved: 300
    [Submit][Status][Discuss]

    Description

    风见幽香非常喜欢玩一个叫做 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 小的那个盘子,每个盘子可重复使用(没有使用次数
    的上限:一个盘子接完一个水果后,后面还可继续接其他水果,只要它是水
    果路径的子路径)。幽香认为这个游戏很难,你能轻松解决给她看吗? 
     

    Input

    第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数。 

    接下来n-1 行,每行两个数 a、b,表示树上的a和b 之间有一条边。树中顶点
    按1到 n标号。 接下来 P 行,每行三个数 a、b、c,表示路径为 a 到 b、权值为 c 的盘子,其
    中0≤c≤10^9,a不等于b。 
    接下来Q行,每行三个数 u、v、k,表示路径为 u到 v的水果,其中 u不等于v,你需要选择第 k小的盘子,
    第k 小一定存在。 
     

    Output

     对于每个果子,输出一行表示选择的盘子的权值。 

    Sample Input

    10 10 10
    1 2
    2 3
    3 4
    4 5
    5 6
    6 7
    7 8
    8 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

    Sample Output

    442139372
    333042360
    442139372
    283254485
    283254485
    217394434
    217394434
    217394434
    217394434
    217394434

    HINT

    N,P,Q<=40000。 

    Source

     
    [Submit][Status][Discuss]

    先考虑每个盘子都会是哪些水果的子路径,不妨设$dep[u] leq dep[v]$,且$t=lca(u,v)$,那么需要分两种情况讨论——

    1.$t ot = u$

    此时发现,水果路径的起点和终点必须分别在$u$和$v$的子树中,可以转化为$x in [ arv[u],lev[u] ], y in [ arv[v], lev[v] ]$这样一个矩阵。

    2.$t = u$

    此时,终点应该在$v$的子树中,而起点只要不在$p$子树中即可。其中$p$为$u$的儿子且$p$为$v$的祖先。这个可以转化为之多两个矩阵。

    然后问题就是每次给矩阵之内的所有点上打个权值,查询某个点上的第$K$权值。这个用整体二分套扫描线+线段树(或树状数组)完成。

    貌似不是很好写(50行应该写不完吧),代码暂无。

    @Author: YouSiki

  • 相关阅读:
    pyhanlp 实体命名识别
    NABCD需求分析
    源代码
    遇到的问题和解决方法
    运行及总结
    测试与调试
    读《一个程序猿的生命周期》和《人,绩效和职业道德》有感
    面向对象程序设计
    设计类图
    SRS文档
  • 原文地址:https://www.cnblogs.com/yousiki/p/6598903.html
Copyright © 2011-2022 走看看