zoukankan      html  css  js  c++  java
  • CF. 966E. May Holidays(树剖/虚树 分块)

    题目链接

    是19年四五月看的题,但咕咕了


    (Description)
    给定一棵树,在树上每个点处有(1)个人,每个人有一个忍耐程度(t_i)。当一个人子树内放假的人数(gt t_i)且他没有放假的时候,他会删库跑路。初始时所有人都没放假。有(m)次操作,每次将一个人由放假变为不放假或由不放假变为放假,然后输出一共有多少个人会删库跑路。
    (n,mleq10^5, 0leq t_ileq n)

    (Solution)
    (Sol1)
    (A_i=t_i-x)(x)(i)子树内有多少人放假了。就是维护(A_ilt0)且没有放假的人的个数。
    树剖+分块。对DFS序分块。记(s[i][j])为第(i)块内(A_x=j)且没放假的人的个数。每次修改只会影响一个位置的值,很容易维护。
    一个空间上的优化是,记(tag[i])为第(i)块的整体加标记。我们限制(s)的第二维在([-D,D])范围内(只在这个范围内统计),这样空间就是(O(块数*D))的。因为(|tag[i]|lt D)时显然不会有(x)影响答案。而当(taggeq D)时,暴力重构这个块即可。

    (Sol2)
    虚树+分块。对询问分块,每次处理(O(B))个询问。容易发现树被分成了(O(B))条链,同一条链上的点,被修改的值是相同的。
    我们可以(O(B))建出虚树。考虑如何回答每次询问。设(A_i=t_i-x),把每一条链上的点先按(A_i)排序,然后维护一个指针,表示当前第一个(lt0)的位置在哪。将重复的(A_i)合并到一起,每次更新一条链最多只会移动一下指针,是(O(1))的。排序可以用基数排序。
    处理完(B)个询问后更新一下所有(A_i)即可。
    复杂度(O(frac{n^2}{B}+nB)),也就是(O(nsqrt n))


    代码咕了(两年半了),见 http://codeforces.com/contest/966/status/E?order=BY_CONSUMED_TIME_ASC

    
    

    无心插柳柳成荫才是美丽
    有哪种美好会来自于刻意
    这一生波澜壮阔或是不惊都没问题
    只愿你能够拥抱那种美丽

  • 相关阅读:
    C++ STL——list
    C++ STL——deque
    C++ STL——string和vector
    C++ STL——C++容器的共性和相关概念
    C++ STL——输入输出流
    C++ STL——异常
    C++ STL——类型转换
    C++ STL——模板
    使用PYTHON统计项目代码行数
    在Ubuntu 16.04 LTS下编译安装OpenCV 4.1.1
  • 原文地址:https://www.cnblogs.com/SovietPower/p/15254198.html
Copyright © 2011-2022 走看看