zoukankan      html  css  js  c++  java
  • 【GDOI2018】所有题目和解题报告

    使用说明:题意和数据范围都只是回忆内容,仅供参考。题解陆续补上。

    Day 1

    第一题

    题意:给定n个数字,要求划分成k的连续段使得每个连续段内的数字之和相同,求最大的k。n,Σai<=10^6。
    算法:模拟
    题解一:记sum=Σai,从大到小枚举sum的因子暴力O(n)判断,10^6范围内的因子个数至多200~300个,且数据无法构造卡到上限(中途退出),可以轻松通过。
    题解二:统计所有前缀和记录到同数组b[]中(即b[i]表示存在大小为i的前缀和),从大到小枚举sum的因子x后,计算每一个k*sum/x(1<=k<=x)在b[]中是否出现即可。复杂度O((sigma_1(sum))),其中(sigma_1(sum))表示sum的约数和。

    第二题

    题意:给定n个0~m-1的数字,每次操作可以在模m意义区间+1或区间-1,求最少几次操作可以使所有数字变成0。n,m<=10^5。
    算法:差分+贪心
    题解:如果不考虑模m意义就是一道经典题目。差分后区间操作变成一次+1和-1。差分后实际上有n+1个数字,而第n+1个数字可以任意改变。那么差分后正数之和为A,负数之和为B,那么ans=max{A,B}。
    现在考虑模m意义,把所有数字转化为非负数,要选择一些数字变成0,另一些数字变成m。为了使答案尽可能小,变成0一定优先选小,变成m一定优先选大,所以排序后贪心从两边取维护A和B的平衡即可(也可以枚举分界点。
    复杂度O(n)。

    第三题

    题意:给定n个点的带点权树,每天早上根的数字变成0,每天下午每个点的数字往根移动,每天晚上会有一些单点加值的操作。给定m个操作,每个操作在第ai天晚上在点bi加上数字ci。给定k个询问,每次询问第ai天凌晨的【以bi为根的子树】的数字和。n,m,k<=10^5。
    算法:CDQ分治 或 树套树
    题解:先不考虑修改操作,对每个点x记深度d[x],dfs序入栈序in[x]和出栈序out[x]。一个点x会在询问(ai,bi)中被统计当且仅当满足(d_x leq a_i)(in_{b_i} leq in_x leq out_{b_i})。关键在于把子树看成dfs序后,这就是个二维偏序问题了。
    对于修改操作(ai,bi,ci),将深度维改为深度+时间维,所有初始节点时间默认为0,修改就在bi下面接一个时间为ai权值为ci的点即可。
    但是这样还有一个问题,就是由于离线操作,时间靠前的询问可能统计到时间靠后的询问(因为深度和时间加起来计算了),所以需要再加一个时间维。
    这样就是三维偏序问题,用CDQ分治解决,复杂度(O(n log^2n))

    第四题

    题意:给定n个点的竞赛图,m条已知的点不相交简单路径,其余边方向随机,求形成强连通分量个数的期望。
    算法:

    Day 2

    第一题

    题意:给定n个点m条边的无向图,第i个点有权值ai,边(x,y)的权值定义为:

    [w(x,y)=sum_{i=1}^{a_x}sum_{i=1}^{b_x}[(i,j)=1]i+j ]

    可以选择一个数字p,使得所有边的权值都减少p(至多减到0),给出限定值T,求最小的p满足1~n的最短路<=T。
    n,m<=20000,ai<=10^5,T<=10^18。
    算法:莫比乌斯反演+二分最短路
    题解:对于两点权值为a,b的边权w:

    [w=sum_{i=1}^{a}sum_{i=1}^{b}[(i,j)=1]i+j ]

    莫比乌斯反演易得:

    [w=sum_{d=1}^{min{a,b}}mu(d)*dsum_{i=1}^{frac{a}{d}}sum_{i=1}^{frac{b}{d}}i+j ]

    后面部分直接计算:

    [sum(a,b)=a*frac{b(b+1)}{2}+b*frac{a(a+1)}{2} ]

    复杂度(O(m sqrt{a_i}))
    预处理所有边权,二分p计算最短路判断即可。最短路数组记得初始化为比1e18大的数字。

    第二题

    题意:给定n个点的树,定义f(S)为点集S的导出子图的边数,求(sum_{S}f(S)^k)。n<=10^5,k<=10。

    第三题

    题意:给定n个二元组(xi,yi),两个二元组i和j的价值定义为(|x_i-x_j|*max{y_i,y_j}),一个区间[L,R]的价值是其中任选两个二元组的最大价值。
    给定m个操作,修改一个二元组的x或y,询问一个区间的价值。
    n,m<=10^5。
    数据保证初始的y和修改的y随机生成。

    第四题

    题意:给定n个点的无向图邻接正边权矩阵。每个点可能正在维修(不可经过)。k次操作,询问点x出发回到x的最短路径,或改变一个点的维修状态。n,k<=400。
    算法:dijkstra
    题解:T4也出走路题,想不到吧!
    从点x出发回到x的最短路径就是最短简单环。
    每次询问将点x删除后将与点x有直接连边的点标记为关键点,那么就是求解关键点两点间最短路的最小值。(与x的连边边权只要在最短路初始值设置的时候修改即可)
    解决这个问题,将关键点作为起点集进行dijkstra,访问到一个点的最短路(第一次访问)和次短路(第二次访问)加起来就是这个点对答案的贡献,取最小值就是答案。
    修改操作是假的。

    Day 3

    第一题

    题意:给定n个人的三元组(ai,bi,ci),一个人能打败另一个人当且仅当至少有两个属性大于另一个人,数据保证没有两个人的同一个属性相同。
    共进行n-1轮游戏,每轮任选两个人淘汰败者,求哪些人可能成为最后留下的人。n<=10^5。
    算法:主席树+Tarjan缩点。
    题解:朴素做法是暴力求出两两有向边的方向,然后对竞赛图缩点后有一条哈密顿路径,唯一那个入度为0的强连通分量包含的点数就是答案。
    证明比较显然,①有入度的强连通分量一定不可能淘汰掉入度到它的强连通分量,②入度为0的强连通分量一定有哈密顿回路(竞赛图的性质),故让其中某个点x留到最后只需要从它上一个点开始往前一直两两淘汰,最终就会剩下x的下一个点。
    现在的问题是边数太多了,但有很多冗余边。假设只有a,b,那么所有店按a排序后以b为下标建主席树(可持久化权值线段树),每次父亲向儿子连边以及新链叶子向依赖链叶子连边,然后每次的点向直接引用依赖链的左子树连边,这样建图后连通关系就完全等价于上面的建图了。建三棵主席树ab,ac,bc连边即可。
    复杂度O(n log n)。

    第二题

    题意:给定n个点构成的完全二叉树,即点n的父亲是点(frac{n}{2}),边权为(an^2+bn+c),其中a,b,c为给定的常数。有m次删除以某个点x为根的子树(可能重复删除),每次删除后要求找一个点x,满足所有点到它的距离和最短,求点x和距离和。n,m<=10^5,a,b,c<=10^9。

    第三题

    题意:给定V个点E条边的无向图,有一个长度为n的小写字母串,有m只猴子各自携带一个子串要从1到V,两只猴子的路径如果有边相交那么会发生强度为两个子串的LCP的叫嚣。要求安排所有猴子的路径使得所有叫嚣的最小值最大。V,E<=10000,n,m<=10^5,保证80%的边直接从1到V。
    算法:最大流+二分哈希
    题解:首先如果知道有k条边不相交的路径可以从1到V,那么二分叫嚣值L,如果两个子串的LCP>=L那么它们可以在同一条路径上,而且LCP>=L的性质有传递性,所以直接用桶记录每个子串长度为L的前缀就可以知道至少需要多少条路径,判断是否>k即可。
    如何知道从1到V有多少条边不相交的路径?将所有边转化为流量为1的边,跑最大流就是答案。

    第四题

    题意:对一个黑白格图进行大模拟得到一棵带点权树,求树的直径(点权和)长度为x,然后要求将x划分成若干个整数的方案数之和。n<=10^5。

    复杂度(O(n sqrt n))

  • 相关阅读:
    「NOI2017」蔬菜 解题报告
    线性代数
    idea创建maven的web工程
    logback和slf4j的使用之logger使用
    英雄之言 罗隐
    论英雄
    英雄--偶得佳文不知出处
    日志
    延迟加载线程安全的单例--最佳方式,通过内部类
    linux下安装jdk8
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8984144.html
Copyright © 2011-2022 走看看