zoukankan      html  css  js  c++  java
  • 图上的游戏

    16分做法:考虑bfs树,但是需要改造。
    在bfs过程中,我们一点一点拓展和根节点距离为(d)的点。
    考虑每次批量拓展距离为(d)的点。
    求出一个点的所有出边可以:
    把一个点到根的所有边点亮,然后枚举每条边(i),每个点(j),如果点亮(i)(j)和根节点连通,则(j)(i)这个出边
    点亮(i)的每个出边(编号)和到根的所有边(编号),查询距离(>d)的所有点(k),如果和根节点连通,则(i->k)有一条边。
    考虑距离为(d)的点和距离(>d)的点的所有边,凭借这些边显然可以知道bfs树的深度为(d+1)的所有节点的父亲边和(leq d+1)的所有点的导出子图里的边。
    操作次数(O(n^2m))
    33分做法:
    考虑随机化整体二分
    如果随机边,则我们不知道点的信息,不太能做。
    (solve(s1,s2))表示现在边集合为(s1),点集合(s2)
    (card(s2)=1)时把(s2)的元素插入答案序列的末尾。
    否则考虑每次随机取一个点(x),把所有边点亮后把(s1)的所有边删除。
    如果删除后(x)(0)连通则这条边在(x)右边,否则在(x)左边。
    考虑每个点的位置,把所有左边的边全部点亮,如果当前点(y)(0)连通,则把(y)归到左边,否则归到右边。
    由于随机数据笛卡尔树的期望深度和,所以操作次数(O(nlog_2n))
    57分做法:
    一个(O(n^2))和标算不同的做法:考虑类似33分一样把所有边依次删除后,询问某个点(x)是否和(0)连通。
    这样子得到了一个点到根的所有边的集合。
    设第(i)个点到根节点的集合为(s_i)
    如果(card(s_i)+1=card(s_j),card(s_j-s_i)=1),显然(i)(j)有边,可以报告答案。
    不知道为什么不给这个部分分,感觉还是和标算有点关系的。
    一个(O(nlog_2n))的做法:此部分并非独立想出。
    参考题解划分成链,标记边后均摊(这个trick又没有想到,见过好几次了。。。。)和"父亲比儿子小序"。
    考虑把树划分成链(随便剖分),使得每个点在且只在一条链上。
    根据前面的启发,考虑从小到大循环每个点,设循环到(i)
    由于我们擅长求出当前点到根的边,考虑维护(0)([1...i])的点的链并。
    在插入(i)时,我们希望在均摊新点个数(log_2n)的时间复杂度内找到(i)到根节点上比链并新增的边。
    考虑一个序列(A),它包含(0...n-2)(n-1)条边,把所有已经在链并的所有边删除。
    问题转化成:有若干个被标记的点,可以询问一个集合内是否包含标记点,希望在标记点个数(log_2n)的询问次数求出所有标记点。
    这是经典问题,可以二分。
    新增的边一定是链状的。
    考虑新增边接在哪条链上,然后求出接的边在这条链的那个位置。
    前者可以二分,像树上分治fft一样,定义链的序为它的链头的dfs序
    (实际上让父亲的编号比儿子小即可)
    在二分的过程中把([1,md])的链上的所有边和新增边全部点亮,然后询问(i)和根节点是否连通。
    找到位置(md)使得点亮编号([1,md])的链的所有边 ,(i)和根节点连通,而([1,md-1])却不。
    求出接的边在这条链的那个位置,可以在链上二分,点亮所有其他链,找到第一个位置(md)使得点亮拓扑序([1,md])的所有边 ,(i)和根节点连通,而([1,md-1])却不。
    即可求出接的边在这条链的那个位置。
    如果在链尾,则可以把当前链接在链尾,然后用随机整体二分求出当前链的情况。
    否则可以给当前链分配一个比所有链都要大的标号。
    易知这合法。

  • 相关阅读:
    USACO 6.4 章节
    USACO 6.3 章节 你对搜索和剪枝一无所知QAQ
    USACO 6.1 章节
    USACO 5.5 章节
    USACO 5.4 章节
    USACO 5.3 章节
    99乘法表
    mini整数计算器
    python爬虫-爬取天气预报内容
    python实时监控服务器性能
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14609113.html
Copyright © 2011-2022 走看看