这鬼家伙已经咕了好久了……

SDOIR2的题目挺好玩的~

快速查询(???)

不难发现所有的操作都可以通过区间打Tag实现

那么可以维护两个标记\(a,b\)表示序列中的数为\(x\)时实际表示的值是\(ax+b\)。对于一个单点赋值操作把值\(x\)变为\((x-b)a^{-1}\)放进数组里面,对于全局赋值操作直接把数组清空。只清空在上一次清空到这一次清空之间被修改的数组上的位置,那么清空的复杂度一定不会大于前面所有操作的操作次数,复杂度就是对的。

至于怎么存这个数组可以离散化也可以像我一样很呆地手写哈希表

代码

染色(DP)

有一个显然的暴力:设\(f_{i,j,k}\)表示填满前\(i\)列、第\(i\)列两个元素的颜色分别是\(j,k\)的方案数。复杂度三方一分都没有……

考虑在这个DP的状态上压掉一维。注意到如果我们称至少有一个位置有颜色的列是重要列,那么如果我们可以预处理重要列与重要列之间的转移,我们就只需要记录最后的重要列上\(0\)位置处填上的颜色即可,那么DP的复杂度就变成了\(O(n^2)\)。

感觉很不错,我们考虑两个重要列之间的可能状态。设\(x,y\)是其中一个重要列的颜色,考虑另一个重要列的颜色,有以下几种情况。在下面的叙述中用\(?\)表示不与\(x,y\)相同的颜色,一横排的若干个矩阵表示这些矩阵的方案数是相同的。

\(\left(\begin{align*} x && ... && y \\ y && ... && x \end{align*}\right)\)

\(\left(\begin{align*} x && ... && x \\ y && ... && y \end{align*}\right)\)

\(\left(\begin{align*} x && ... && ? \\ y && ... && x \end{align*}\right)\) or \(\left(\begin{align*} x && ... && y \\ y && ... && ? \end{align*}\right)\)

\(\left(\begin{align*} x && ... && ? \\ y && ... && y \end{align*}\right)\) or \(\left(\begin{align*} x && ... && x \\ y && ... && ? \end{align*}\right)\)

\(\left(\begin{align*} x && ... && ? \\ y && ... && ? \end{align*}\right)\)

设\(g_{i,0/1/2/3/4}\)表示这五种状态中间全为\(0\)的列数为\(i\)时的填充方案数,转移枚举最后一个全为\(0\)的列即可,系数有点复杂,可以使用矩阵优化但是我这么无脑的人肯定是直接大力写式子啊

然后去掉头尾的全\(0\)列(因为它们的方案数可以直接贡献到答案里),我们就可以每一次枚举两列,用上面求出的\(g\)数组进行转移了。复杂度\(O(n^2)\)可以通过96pts。

所以最后的4pts当然是打表啦考虑优化DP。

当你写出式子之后就可以发现:其中的所有操作稍作变换可以变为“快速查询”中的区间加、区间乘、单点修改、单点查询、询问所有的和的操作。写一遍不需要离散化的快速查询配上这个DP就可以了。

96pts 100pts

世界地图(最小生成树、虚树)

需要求一个前缀和一个后缀的最小生成树,我们可以先预处理好前缀和后缀的生成树,然后考虑连接前缀和后缀之间的边的影响。

如果已经有边连接了前缀和后缀,那么如果再加入一条连接前缀和后缀的边,那么一定要删掉两个经度为\(1\)的点在前缀最小生成树上的路径的最大边权的边,或者两个经度为\(m\)的点在后缀最小生成树上的路径的最大边权的边。那么可以发现前缀MST和后缀MST上有用的边只是经度为\(1\)和\(m\)的点的虚树上的边。

那么我们预处理前后缀MST的时候也使用同样的方法,计算完MST之后把两边边界上的点在MST上的虚树记录下来,注意到虚树上一条边的边权可以直接赋为这两个点对应MST路径上的所有边的最大边权,那么一个MST中有效的边的数量就是\(O(n)\)级别的,每一次合并的复杂度就是\(O(nlogn)\)。

那么这样做就可以得到一个\(O((m+q)nlogn)\)的做法。

代码

热闹的聚会与尴尬的聚会(构造)

题设相当于\((p+1)(q+1) \geq n\)

考虑如下构造方式:每一次在图中删去度数最小的点和它所连的边直至图为空,设每一次删去的点的序列为\(p_1,p_2,...,p_k\),每一个点被删去时的度数为\(d_1,d_2,...,d_k\),那么周日聚会就邀请\(p_1,p_2,...,p_k\),周六聚会就邀请\(d_i\)取到最大值时对应的图上的所有点。

证明:序列\(p\)的所有点显然独立,而\(d_i\)取到最大值时选择的所有点的热闹度就是\(\max d_i\)。因为\(\sum\limits_{i=1}^k (d_i + 1) = n\),\(k(\max d_i + 1) \geq \sum\limits_{i=1}^k d_i +1 = n\),所以\((k+1) (\max d_i + 1) \geq n + 1\),所以这样的选择方案是合法的。

删点使用set维护就可以了。

代码

移动金币(阶梯Nim、DP)

把第\(i\)个金币和第\(i+1\)个金币之间的空格个数看作第\(m-i\)节阶梯的石子数量,那么这个显然是一个阶梯Nim,有效的石子是奇数节的石子,而偶数节的式子对胜负没有影响。

所以我们只需要考虑奇数节的石子,而对于偶数节的石子直接组合数分配。计算先手获胜的概率似乎并不好算,但是比较好算的是先手必败的方案数,因为这意味着奇数节阶梯石子异或和为\(0\),也就是每一位恰好出现偶数次。发现\(n\)并不是很大,我们可以直接按位背包。复杂度是\(O(mnlogn)\)的,但是实际跑得很快。

代码

连续子序列(记忆化搜索)

发现最近的省选很喜欢出思维的搜索题(隔壁TJOID2T3就是,ZJOID1T1或许也可以算)

之前有一个类似于\(0110\)缩成\(0\)、\(1001\)缩成\(1\)的方法,但是似乎很难避免算重,然后发现有一种更优秀的做法……

考虑T.M.序列的一个性质,可以参考OEIS A010060:令初始序列为\(0\),然后用\(01\)代替\(0\),\(10\)代替\(1\),做无限次就可以得到T.M.序列。

那么如果一个序列是T.M.序列的子序列,也就一定能够通过\(01\)填充为\(0\)、\(10\)填充为\(1\)的方式还原为\(0\)。

那么我们考虑dfs(s , k)表示当前前缀为s、后面还需要填充k个字符的方案数,转移可以考虑枚举填充的方式:有可能是s的\(x(2 \not\mid x)\)与\(x+1\)字符组合,也有可能是\(x(2 \mid x)\)与\(x+1\)字符组合,即在前面加上一个字符使得\(s[1]\)能够和这个字符组合,被一个单独的字符填充。

不难发现当一个串的长度\(>3\)时这样的划分方式是唯一的,证明可以不妨假设两种填充的方式都成立,那么如果在第一种填充方式下填充出了前缀\(00\)或者\(11\),那么在第二种填充方式下就会填充出前缀\(000\)或者\(111\),这是不合法的;而如果填充出了\(01\)或者\(10\),那么在第二种填充方式下根本不可能存在合法的字符串满足条件。

而当串长度\(\leq 3\)时,比如说串\(010\),它就可以被填充为\(01|01\)或者\(10|10\),这两种方案都合法,但是这个字符串只能被计数一次,所以这些地方需要特判。

注意到当\(|s|=1\)时方案数只和\(k\)的大小有关,在这种情况下我们可以进入另一层递归。在这层递归中使用记忆化,那么总的状态数就是\(O(logk)\)级别的,而solve函数的递归总数是\(O(|s|)\)级别的,所以复杂度很小可以通过本题。

代码

SDOI2019 Round2的更多相关文章

  1. 【瞎扯】我的OI之路

    这里大概是一些我自己对我的OI之路的一些记录. 2015.11不知道哪一天-- 我听说了"编程". 当时还不懂得啥是信息学竞赛,以为这只是纯粹的程序设计.后来才明白信息学竞赛是算法 ...

  2. 【ContestHunter】【弱省胡策】【Round2】

    官方题解:http://wyfcyx.is-programmer.com/posts/95490.html A 目前只会30分的暴力……DP好像很神的样子0.0(听说可以多次随机强行算? //Roun ...

  3. Loj #3111. 「SDOI2019」染色

    Loj #3111. 「SDOI2019」染色 题目描述 给定 \(2 \times n\) 的格点图.其中一些结点有着已知的颜色,其余的结点还没有被染色.一个合法的染色方案不允许相邻结点有相同的染色 ...

  4. [SDOI2019]热闹又尴尬的聚会 构造,贪心

    [SDOI2019]热闹又尴尬的聚会 链接 luogu loj 思路 第一问贪心?的从小到大删除入度最小的点,入度是动态的,打个标记. 当然不是最大独立集. 第二问第一问的顺序选独立集,不行就不要.选 ...

  5. [SDOI2019]快速查询——模拟

    题目链接: [SDOI2019]快速查询 对于整个序列维护一个标记$(k,b)$表示序列的每个数的真实值为$k*a_{i}+b$(注意要实时维护$k$的逆元),并记录序列的和. 对于单点修改,将$a_ ...

  6. [SDOI2019]快速查询

    [SDOI2019]快速查询 [题目链接] 链接 [思路要点] 据说是 \(\text{SDOI2019}\) 最水的题 操作次数为 \(1e7\) 范围,显然要求每次操作 \(\mathcal{O} ...

  7. SDOI2019热闹又尴尬的聚会

    P5361 [SDOI2019]热闹又尴尬的聚会 出题人用脚造数据系列 只要将\(p\)最大的只求出来,\(q\)直接随便rand就能过 真的是 我们说说怎么求最大的\(p\),这个玩意具有很明显的单 ...

  8. noip2016十连测round2

    A: Divisors 题意:给定 m 个不同的正整数 a 1 ,a 2 ,...,a m ,请对 0 到 m 每一个 k 计算,在区间 [1,n] 里有多少正整数 是 a 中恰好 k 个数的约数. ...

  9. DUT Star Round2

    A.Zeratu的军训游戏 Problems: 开灯问题,问无数次操作之后第n盏灯的状态 Analysis: cj:平方数有奇数个约数 Tags: Implementation B.Zeratud的完 ...

随机推荐

  1. 洛谷 P2897 【蚯蚓】 题解

    先分析一下题意: 这个题说的就是一开始给你很多条蚯蚓,然后给出你规定的次数,每一次都从蚯蚓里面拿出最长的来切成一条是原来q倍的,另一条是原来的(1 - q)倍,把切开的两条再放回去.规定次数完成之后, ...

  2. 现有某电商网站用户对商品的收藏数据,记录了用户收藏的商品id以及收藏日期,名为buyer_favorite1。 buyer_favorite1包含:买家id,商品id,收藏日期这三个字段,数据以“\t”分割

    实验内容(mapReduce安装请按照林子雨教程http://dblab.xmu.edu.cn/blog/631-2/) 现有某电商网站用户对商品的收藏数据,记录了用户收藏的商品id以及收藏日期,名为 ...

  3. firewalld添加/删除服务service,端口port

    启动CentOS/RHEL 7后,防火墙规则设置由firewalld服务进程默认管理. 一个叫做firewall-cmd的命令行客户端支持和这个守护进程通信以永久修改防火墙规则. # firewall ...

  4. maven工程中MENIFEST.MF中属性作用

    Manifest-Version: 版本号 Bundle-ManifestVersion: bundle的版本号 Bundle-Name: bundle的名称,主要是对bundle的作用的说明 Bun ...

  5. Spring 整合 myBatis

    思路 数据库连接池交给 Spring 管理 SqlSessionFactory 交给 Spring 管理 从 Spring 容器中直接获得 mapper 的代理对象 步骤 创建工程 导入 jar 创建 ...

  6. Anaconda3_5.3.1+Pycharm2018.3安装步骤

    最近更新了Anaconda软件,重新配置了以下Python开发环境,结果之前旧环境开发的好好的程序竟然跑不起来.网上各种搜索,各种找答案还是没有一篇靠谱的文章教我把问题解决.走了各种弯路,足足整了几天 ...

  7. Spring cloud微服务安全实战-8-1课程总结

    总结 首先讲了api的安全.安全常见的风险.安全措施.然后我们把简单的api演化成一个这种微服务的架构. 首先讲了在网关上可以做哪些安全的措施.然后讲了如何搭建一个安全中心,也就是认证服务器,包括一些 ...

  8. BUG处理流程图

    流程描述: 1. 测试人员发现bug提交给开发. 2. 开发人员判断是否是bug. 3. 如果是bug,进行修改,修改完成后更改bug状态为已解决. 4. 如果不是bug,退回给测试人员并描述退回原因 ...

  9. MUD游戏开发教程视频

    MUD游戏开发教程视频 https://space.bilibili.com/476328540/channel/detail?cid=91187

  10. dataTable.NET的column index的不同定義

    dataTable.NET是一個jQuery的plug in 第三方的library, 用來實現web page中table的interaction controls, 另外最近有在用的還有Teler ...