Codeforces Round #588 (Div. 1)

2023-05-16

Contest Page

因为一些特殊的原因所以更得不是很及时……

A

sol 不难发现当某个人diss其他所有人的时候就一定要被删掉。

维护一下每个人会diss多少个人,当diss的人数等于剩余人数$-1$的时候放队列里,每一次取队头更新其他人diss的人数。

code

B

sol 一个结论:对于序列$a_1,a_2,...,a_n$,其前缀$gcd$数量不超过$log_2a_i$种。证明考虑从前往后计算前缀$gcd$,那么从第$i-1$个$gcd$到第$i$个$gcd$,数值要么不变要么至少除以$2$。

所以dfs维护一下每个点到根的路径上的每种$gcd$和其范围就可以算答案了。

code

C

sol 首先算答案可以枚举三元组$(i,j,k)$的$j$就可以用入度数量乘出度数量更新答案。实现的话似乎直接建反图暴力更新是对的,但是我的写法比较鬼畜:

按照度数根号分治,对于度数$\leq \sqrt{n}$的暴力,对于度数$\geq \sqrt{n}$和度数$\geq \sqrt{n}$之间的边暴力,对于度数$\geq \sqrt{n}$和度数$\leq \sqrt{n}$之间的边,在度数$\geq \sqrt{n}$的点用一个队列记录下有多少个$\leq \sqrt{n}$的点指向它,每一次修改的时候把队列里的元素清掉。这个复杂度显然是$O(q\sqrt{n})$的。

分析一下直接建反图的复杂度:设每个点的势能函数为连到它的点的数量,对于度数$\leq \sqrt{n}$的点它们的势能函数值不超过$\sqrt{n}$所以每一次操作的复杂度不超过$\sqrt{n}$;对于度数$\geq \sqrt{n}$的点每一次操作不会使得这些点的势能函数之和增加超过$\sqrt{n}$,所以是均摊$\sqrt{n}$的。所以复杂度就是$O(q\sqrt{n})$。

code

D

sol 先写标算做法。先把每个排列康托展开压成一个数,然后设$f_{i,j}$表示排列$i$经过置换$j$换一次之后会到哪里。这个可以$O((k!)^2k^2)$做。

枚举右端点$r$对于所有左端点计算答案。考虑如果我们可以通过已经拥有的置换从$i$变为$j$就连边$(i,j)$,那么现在相当于要求对于所有左端点将所有这样的边加进去之后$0$所在的联通块大小。

然后根据群论拉格朗日定理,我们可以知道对于区间$(1,r)$来说有用的置换最多只有$log_2k!$种,于是记录一下对于每一个右端点来说每一个置换最后出现在哪里,每一次取一个在图中$0$走不到的出现在最右的排列加进置换群中,用bfs更新一下可以到达的排列然后贡献答案。复杂度应该是$O((k!)^2k^2+nk!(k+log_2k!))$的……

然而上面的做法非常鬼畜,我们考虑一个清新一点的做法:

我们认为边$(i,j)$的边权是能将排列$i$变为排列$j$的置换的最晚出现时间,那么有用的边显然只会在这个图的最大生成树上。我们每一次移动右端点相当于加入$k!$条边,用Kruskal维护一下,然后在最大生成树上求出每个点到$0$的瓶颈路长度,那么当左端点小于等于这个长度的时候这个排列就可以出现。所以就用所有瓶颈路长度和贡献答案就行了。这个的复杂度应该是$O(nk!log_2k!)$的?反正我没写。

code(标算)

E1

sol Meet-in-the-middle。设$f_i$表示右端$R_1,R_2,R_3$三个点能够匹配左边的三元组的集合为$i$的概率,其中$i$是一个$\binom{6}{3} = 20$位二进制数,第$0$位表示匹配$(L_1,L_2,L_3)$,第$1$位表示匹配$(L_1,L_2,L_4)$,以此类推。这个东西可以$O(2^{\frac{n^2}{2}}\binom{n}{3})$爆搜。

再设$g_i$表示右端$R_4,R_5,R_6$能够匹配左边的三元组的补集集合为$i$的概率,也就是说这里表示第$0$位表示匹配$(L_4,L_5,L_6)$,第$1$位表示匹配$(L_3,L_5,L_6)$,以此类推。

那么我们要求的就是$\sum\limits_{i} f_i \sum\limits_{i \land j = 0} g_j$,后面那部分东西可以高维前缀和计算。

代码没写

E2

sol 设一个$128$位数$k$表示当前有哪些$L$的子集能与当前的$R$匹配。因为Hall定理等各种因素,能够满足二分图匹配条件的$k$的数量只有$S=64184$种,我们考虑把这些状态搜出来。我们用bitset存$k$,每一次考虑在当前的$R$上新加入一个点,枚举$R$的连边情况然后更新$k$的取值。这一部分的复杂度可以做到$O(S\frac{n2^{2n}}{w})$,稍微大一点也没关系反正跑得过。

在搜索的过程中用unordered_map把状态哈希起来并记录右边新加入的点的连边情况分别是什么时会转移到哪个状态。然后DP:设$f_{i,j}$表示当前决定了$R$中的前$i$个点的连边,当前匹配状态为$j$的概率。转移暴力枚举当前点转移。

复杂度$O(S\frac{n2^{2n}}{w} + nS2^n)$。

code

F

sol 设$x_i$表示从$i$到$i+1$的coin数,如果$x_i < 0$表示有$|x_i|$coin从$i+1$到$i$,$x_0 = x_n$。当$x_1,x_2,...,x_n$确定了之后可以很容易构造出步数为$\sum\limits_{i=1}^n |x_i|$的方案(而且这是下界),所以题目就变成了在满足$\forall i , a_i - x_i + x_{i-1} \in [l_i,r_i]$的情况下最小化$\sum\limits_{i=1}^n |x_i|$。

枚举$x_1$然后DP:设$f_{i,j}$表示决定了$x_1,x_2,...,x_i,x_i=j$时$\sum\limits_{k=1}^i |x_k|$的最小值。那么$f_{i,j}$就由$f_{i-1,k} , k \in[a_i + j - r_i , a_i + j - l_i]$转移而来。初始值$f_{1,x_1}=|x_1| , f_{1,others} = inf$。

把$f_{i,j}$视作以$j$为自变量的离散函数$f_i(x)$,那么从$f_{i-1}(x)$到$f_{i}(x)$需要做这些事情:1、将$f_{i-1}(x)$往左平移$(a_i-r_i)$;2、令$g(x) = \min\limits_{i=x}^{x+(r_i-l_i)} f(i)$;3、$f_{i+1}(x) = g(x) + |x|$。

如果$f_{i-1}(x)$是凸包那么$f_i(x)$也是凸包,而$f_1$的定义域只有$x_1$,所以$f_i(x)$就是凸包。对于凸包一个实用的维护方法是维护拐点,一个拐点表示右边线段比左边线段斜率大$1$,这样就可以描述整个凸包了。这样维护可能会导致堆中有多个相同元素,这没有什么关系。

$1$操作打个横坐标全局标记就行,$2,3$操作有点难搞。分析一下$2$操作的实质,假设最小值在$p$点处取到,那么相当于在$[p-t,p]$插入一条斜率为$0$的线段,然后把左边的凸包左移$t$。而操作$3$相当于位置>0的所有线段的斜率增加$1$,<0的所有线段斜率减少$1$。

要做一个区间$x$坐标增减、区间斜率增减、动态插入拐点、求全局最小值的问题。这个显然可以Treap解决,但是一种更优秀的做法是用两个堆分别维护右侧线段斜率>$0$和$\leq0$的所有拐点,1操作全局标记,2操作在$\leq 0$对应的堆打标记,3操作按情况,在两个堆中插入拐点、维护两个堆之间拐点的变化情况。因为每一次3操作斜率变化至多1所以至多有一个拐点在两个堆之间移动。

还有一个棘手的问题是初始状态。我们可以认为初始状态是左边有$N+5$个$x_1$位置的拐点,右边有$N+5$个$x_1$位置的拐点。这相当于$x_1$左右的射线斜率都是$N+5$,每一次操作至多修改$1$的斜率,所以这些直线一定取不到最优值。

我们可以对于一个确定的$x_1$在$O(nlogn)$时间内求出其答案了,我们现在需要解决所有$x_1$的答案的最小值。接下来是魔法时间:

1、当$x_1$为实数时最优解不变。可以把这个问题变为一个上下界网络流问题,类似于 糖果传递。然后根据一个我也不知道怎么证明的定理:容量和费用都是整数的费用流一定存在一个最优解满足所有边流量都是整数,那么$x_1$为实数时最优解不变。这个引理帮助我们将$x_1$的范围由整数域拓展为实数域。

2、设有两组可行的$(x_1,x_2,...,x_n)$的取值为:$(p_1,p_2,...,p_n),(q_1,q_2,...,q_n)$,那么$(c_1=\frac{p_1+q_1}{2} , c_2=\frac{p_2+q_2}{2} , ..., c_n=\frac{p_n+q_n}{2})$也是一组可行的$(x_1,x_2,...,x_n)$。证明考虑:$a_i-p_i+p_{i-1} \in [l_i,r_i] , a_i - q_i + q_{i-1} \in [l_i,r_i]$,而$a_i - c_i + c_{i-1} = \frac{2a_i - (p_i+q_i) + (p_{i-1}+q_{i-1})}{2} = \frac{1}{2}(a_i-p_i+p_{i-1}+a_i - q_i + q_{i-1})$,两个数同时在一个区间内,那么它们的平均数也显然在这个区间内。

3、设$f(x)$表示$x_1=x$时的DP最优解,根据2的推导,如果$x_1=p_1$时$(p_1,p_2,...,p_n)$取到最优,$x_1=q_1$时$(q_1,q_2,...,q_n)$取到最优,那么$(r_1,r_2,...,r_n)$是一组可行解,它不一定最优,但是因为$|r_i| = \frac{|p_i+q_i|}{2} \leq \frac{|p_i| + |q_i|}{2}$,也就是说一定会有$\sum |r_i| \leq \frac{\sum |p_i| + \sum |q_i|}{2}$,即$f(\frac{p_1+q_1}{2}) \leq \frac{f(p_1) + f(q_1)}{2}$。根据琴生不等式,函数$f$就是一个一阶导数单调递增的凸函数,在其上有极小值。

于是我们只需要用三分法找到$f(x)$在整数域上的极小值就可以了。复杂度$O(nlognlog \sum a_i)$。

code

转载于:https://www.cnblogs.com/Itst/p/11621057.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Codeforces Round #588 (Div. 1) 的相关文章

  • div点击事件 鼠标放上去显示小手

    div cursor pointer
  • 1500*C. Tenzing and Balls (线性DP)

    解析 每次选择两个相同的数 删去他们以及他们之间的所有数 问最多可以删除多少 DP 对于某个位置 i 其前面有多个 j 使得 a i a j 所以使用 f i 来记录前 i 个数能够删除的最大值 include
  • innerHtml用法

    innerHtml用法 span span
  • Petya and Exam【Codeforces 1282 C】【贪心】

    Codeforces Round 610 Div 2 C 有N道题目 题目有简单与困难之分 简单的题目花费A分钟 困难的题目花费B分钟 那么考试时间一共有T的情况下 我们是可以提前交卷的 但是有些时间限制 就是譬如说你现在第x分钟交卷 但是
  • 1600*D. Constructing the Array(优先队列

    解析 每次找到最长的连续0序列 取其中点置为 i 优先队列维护 优先按照长度排序 相同则按照下标左优先排序 include
  • codeforces 851 #432 div2 C Five Dimensional Points

    Problem codeforces com contest 851 problem C Preference Codeforces Round 432 editorial Codeforces Round 432 Div 2 C Five
  • PostScript之二-操作数栈,栈操作符和数学运算符

    引言 这是第二篇关于 PostScript 的系列文章 本文的主要目的是论述堆栈的操作 操作数栈可能是 PostScript 中最主要的部分 赋值 算术或数学运算 循环和逻辑运算都在这块特殊的存储区内进行 是的 堆栈是一块特殊的存储区 被
  • 动态动态规划(DDP)

    1 Problem E Codeforces 一 题目大意 给你一个无向图 第i和i 1条边的权值是w i 问你每个点不在自己原本的点的代价是多少 会有q组询问 表示修改第i条边的权值 二 解题思路 可以观察到 完成这个操作需要每条边经过两
  • Pineapple Incident【Codeforces 697 A】

    Codeforces Round 362 Div 2 A 简单题 include
  • 【CSS】css样式控制div水平垂直居中的六种方法

    1 绝对定位方法 不确定当前div的宽度和高度 采用 transform translate 50 50 当前div的父级添加相对定位 position relative 如图所示 代码如下 div background red posit
  • Salary Changing【Codeforces 1251 D】【二分答案】

    Educational Codeforces Round 75 Rated for Div 2 D 题意 有N名员工和S元钱 然后我们想知道在每一名员工有薪资要求在 li ri 的情况下 我们如何在总共就S元钱的情况下做到员工薪资的中位数最
  • Codeforces Round #697 (Div. 3) C. Ball in Berland(1400)

    Codeforces 1475 C Ball in Berland 题目分析 这个题其实就是给你一堆坐标 让你找到合适的有多少对 思路分析 坐标的话 首先想到用 pair
  • codeforces 733D--Kostya the Sculptor

    Description Kostya is a genial sculptor he has an idea to carve a marble sculpture in the shape of a sphere Kostya has a
  • 网站开发之DIV+CSS简单布局网站入门篇(五)

    这篇文章主要介绍如何使用DIV和CSS简单布局一个网站的首页 通常将网站划分为顶部 Logo 导航条 中部 页面主要内容 左右栏目 底部 制作方介绍 超链接 这是非常基础的一篇引入性文章 采用案例的方式进行介绍的 希望对你有所帮助 运行结果
  • Discuz!X模板代码解析--Header(头文件)

    Discuz X模板代码解析 Header 头文件 header html这个文件存储于common文件下 这个大家应该不陌生吧 我是每个DIV为小节来讲 头部的核心div我就不加if语句来讲解 因为代码太多了 我会在最下面给大家总结一下
  • Codeforces 1454B Unique Bid Auction(模拟)

    Description 题目大意 找到一个序列中唯一且是最小的那个数的下标 感叹我的语言描述真是越来越精炼了 解题思路 算法标签 模拟 记录每个数字出现的次数以及其下标 然后从1开始寻找 第一个找到的数字的下标就是答案 没什么难度 只是不想
  • Fix a Tree【Codeforces 699 D】【dfs + 树的性质】

    Codeforces Round 363 Div 2 D 题意 有N个点 每个点i都有一个父节点p i 如果 i p i 则是说明i结点是根结点 现在我们给出这样的1 N的p i 这可能是不合法的 问 我们应该最少改变多少个使它变成一棵合法
  • Puzzles【Codeforces 697 D】【树形DP + 期望DP】

    Codeforces Round 362 Div 2 D 我们从1号结点开始 给每个结点标序 问的是每个结点的序号的期望是多少 输出这N个结点的期望 那么1号点的期望一定就是1了 对于其他的点呢 可以举例这样的一幅图 首先我们可以确定1 因
  • Educational Codeforces Round 149 (Rated for Div. 2)A~D

    Grasshopper on a Line 题意 给出n和k 求从0到n最少走几步 以及步长 要求步长不能整除k 思路 从n往下找到 k不等于0的数 输出该数和n 该数即可 如果n k 0 那就只需要一步 代码 gt File Name a
  • Python中保留两位小数的几种方法

    保留两位小数 并做四舍五入处理 方法一 使用字符串格式化 gt gt gt a 12 345 gt gt gt print 2f a 12 35 gt gt gt 方法二 使用round内置函数 gt gt gt a 12 345 gt g

随机推荐