WC2017 Day1
字符串算法
0x00 字符串的性质
-
字符串的周期(period):例如abcabca 周期为3
-
字符串的border :相同前后缀
-
显然如果一个长为s字符串有长度为r的border,则其有长度为s-r的period
-
border有什么用?KMP
-
后缀数组:可以求两个子串的最长公共前缀(LCP)
-
LCP和周期性:如果一个字符串有周期p,则i与i+p的LCP为s-p-i+1
-
Weak Periodicity Lemma:p和q都是s的周期,p+q<=|s|,则gcd(p,q)也是s的周期
-
Periodicity Lemma(周期引理):p和q都是s的周期,p+q-gcd(p,q)<=|s|,则gcd(p,q)也是s的周期
-
这两个定理都十分显然,弱化版可以先证p-q也是周期,然后辗转相减,标准版不予证明
-
字符串匹配 引理:u,v满足2|u|>=|v|,则u在v中所有匹配位置组成一个等差数列,用border的性质和周期引理可证
-
border的结构:s所有不小于|s|/2的border长度构成等差数列,同样用border性质和周期引理可证
-
把border按长度分类:[1,2),[2,4),[4,8)…….每一类里长度都是等差数列,则周期也有类似性质(这一个没听懂,下面所有涉及这个的都没懂)
-
如果|v|>=|w|/2,|v|是2的幂次,且w,v都是s的子串,如何求v在w中的匹配位置?
-
可以用类似倍增求后缀数组的做法,把w中长度为|v|的拎出来排序
0x01 字符串循环移位
- 字符串的循环移位:一般有n种,如果最小周期p|n,则只有p种不同的循环移位,每种出现n/p次
- 循环同构?破环成链,在链上匹配(等差数列)
- 可以优化,需要用到上面没听懂的那个性质
0x02 回文串
-
Manacher
-
回文树
-
引理:s是回文串,s的后缀(前缀)t是回文串当且仅当t是s的border,用显然法证明
-
推论:任意字符串所有回文后缀的长度是logn个等差数列(又是你!)
-
最小回文串拆分:manacher+dp,dp[i]=min{dp[j]+1,s[j..i]是回文串},复杂度O(N^2),可以用上面的推论优化成nlogn
-
判断是否存在非平凡(l>=2)回文串拆分:显然有个n^2 dp做法,和上面的问题一样,然而存在线性做法
-
显然的想法:维护从每个点出发的最短(>=2)回文串,贪心取最短串,尝试证明:
-
设从一点出发实际段长为d,最短段长为f[i]
-
若f[i]>=d/2 可以找到一个更短的前缀回文串:d-f[i]是周期=>2(d-f[i])是周期=>d-2(d-f[i])是border=>d-2(d-f[i])是一个更短的前缀回文串,这里要特判d=2f[i]-1的情况
-
若f[i]i],f[i]+1..d-f[i],d-f[i]+1..d,都是回文串,这里要特判d=2f[i]+1的情况
-
单纯贪心不太好使,三种情况,O(3)转移dp
-
双回文串:a,b都是回文串,则ab是一个双回文串
-
s=x1x2=y1y2=z1z2,如果y1,y2,x2,z1都是回文串,x1
-
判断s能否拆成不超过4个回文串?
-
穷举中间断点,判断前后能否用两个以内的回文串组成,预处理。
0x03 字典序
- 全是后缀数组,没怎么听懂
Ulam 猜数游戏
0x00 内容
- 回答方选择一个数x
- 询问方询问一个集合s,回答方回答x是否在s内
- 回答方可以撒谎不超过k次
- 回答方可以变更选择的数(必须合法)
- 拓展:询问必须事先确定(离线询问)
0x01 策略
先考虑离线情况
提问方
朴素策略:每次询问二进制位上的一位,每次询问重复k+1次,最坏次数是$ left ( k+1 ight ) log_2{n}+1(,对所有k和离线都适用,离线的话要询问k+2次,最坏次数)left ( k+2 ight ) log_2{n}$
- 0 1 2 3 4 5 6 7
- 1 3 5 7 倒数第一位为1?
- 2 3 6 7 倒数第二位为1?
- 4 5 6 7 倒数第三位位1?
问题转化
- 传输一个长为$ log_2{n}$的01串,传输有噪音,有不超过k位被修改
- k=1的情况
- 算法0:朴素算法,每个位置询问3次
- 算法1:每个位置询问2次,加一个奇偶校验,询问最终01串中1的奇偶性
- 算法2:每个位置询问1次,把询问位置1到n标号,设立$ log_2(log_2{n}+1)$个奇偶校验,第k个奇偶校验用于检查二进制位上第k位为1的位置构成的串的奇偶性,同时对整个串设一个奇偶校验
- 算法3:hamming code
细化模型
-
是一个信道编码问题
-
编码 传输 译码
-
编码要求:传输过程中受到噪声影响仍能正确译码
-
等价于将n维空间中的$ 2^n$个点映射到m个点上
在线情况
- k=1时,离线与在线算法的最优解满足:在线<=离线<=在线+1,我不会证
回答方的策略?
- 回答方有两种选择,将游戏引向两种状态
- 哪个状态对询问方更不利?信息熵(不确定性)更大的那个。
- 一个重要的评判策略:如果这个数是x,那回答方还能撒谎的次数p
- 记当前p为i的数有$ w_{i}(个,W是) w_{i}$的有序集合
- 一个状态可以用W表示,开始时的状态$ left { n,0,0,0,0..... ight }$
- 询问方可以直接得到答案的W满足$ sum wi=1$
如何维护W?
- 考虑回答者的视角,按一次询问是否涉及一个数把W分成A询问到,B没询问到两个集合
- yes?相当于你对所有b撒谎了
- no?相当于你对所有a撒谎了
- 以yes为例,$ w_{i}=a_{i}+b_{i-1}$,相当于b被右移一位
如何量化信息熵?
-
设$ V_{q}left(W ight)=sum_{i}{k}w_{i}sum_{j}{i}inom{q}{j}$
-
q表示在q次询问内得出答案
-
此为估价函数(搜索空间的体积)
-
这个玩意取对数就是信息熵
-
感性认识:后面那个组合数就是撒谎方式的数量
Vq的性质
- $ V_{q}left(W ight)=V_{q-1}left(W_{yes} ight)+V_{q-1}left(W_{no} ight)$
- $ V_{q}left(W ight)leqslant 2^q$是能在q次询问内得出解的必要条件
根据第二条性质,可以用$ V_{q}$评价一个状态
这就可以搞了,回答方根据这个估价函数决定回答策略
再回头看询问方的策略?
- 相当于n个数$ a_{i}$,分成两堆,要求差最小
- 没有多项式做法,可以贪心(论文《论一类启发式算法在信息学竞赛中的应用》)
0x02 Ulam游戏的实质
- k=1时,其实是容错的二分搜索
- 如果$ k eq 1$?
- 变成了一个k+1划分问题
- 回答方:性质2变成$ V_{k,q}left(W ight)=sum_{i}{k}wisum_{j}{i}left(k+1 ight) inom{q}{j}leqslant k^q$
0x03 其他问题
有一堆球,其中有一个比其他球轻一些,要求只用一架天平,用最少的次数找出这个球
- 三叉搜索,要求其中两个集合大小一样
- 如果天平有不超过k次会出错?
- 容错三叉搜索问题
N个数,大小未知,比较器会有不超过e次出错,用最少的比较次数求其中最大项
- 朴素策略,每次疯狂询问,直到一个返回值出现大于e+1次
- 理论复杂度(e+1)(n-1)+e
- 然而这是理论最优
- 构造一个回答策略,前(e+1)(n-1)-1次询问如实回答
- 定义“负票”这个概念:如果比较器返回了a比b小,则称a收到一张负票
- 显然如果一个数收到e+1张负票,那这个数不可能是最大值
- 前面的一阶段的询问中显然有一个$ x_{m}(收到的负票小于等于e,且有一个数) x_{n}$没有收到负票
- 在后面的e个询问中,运用撒谎不让$ x_{m}$收到的负票超过e
- 最后询问方无法确定$ x_{n}(还是) x_{m}$是最大值,需要再询问一次,总数是(e+1)(n-1)+e
容错排序,没有重复元素,不考虑常数
- 随便选一个$ nlog_2{n}(比较排序,运用前面的思路可以得到一个) enlog_2{n}$排序
- 考虑插入排序,平衡树维护序列
- 插入时不考虑出错问题
- 插入后和前驱后继元素O(e)比较一下
- 最终复杂度$ O((n+e)log_2{n}+(n+e)e)$ log是插入,e是判错
IOI2016 题解
练习赛前三题都是傻逼题,按下不表
练习赛T4
有一个01串S,你每次可以询问一个01串是不是S的子串,最终要求输出S
- 36分,贪心向后加01,不能加了以后向前加01,期望复杂度2n
- 100分:
- 做法1:贪心加01,但只询问一次,如果连续询问k次都不对,就认为长度过长了,在这个后缀里二分求出最长长度,k取15可过
- 做法2:确定性算法,先二分出最长全0串长度为l,向后加1并判断,如果连续l+1个不合法就说明过长,复杂度貌似很大,实际是$ n+2log_2{n}$可过
D1T1
有n个数$ a_{i}(,要求找出一个集合B使) sum bi in [L,R](,满足) R-L>a_{max}-a_{min}$
- 从小到大排序,贪心往里加直到加不下,设当前加不进去的一个数是$ a_{k}(,由于题目给出的性质,) a_{k}-a_{1}(肯定能加进去,那把) a_{k}(加进去,) a_{1}$删掉,继续往后扫
- 答案一定是一个连续区间或者是前缀和+后缀和
- 做法多种多样
D1T2
有一些铁轨,每个铁轨i要求进入速度不大于$ s_{i}(,出来速度会变成) t_{i}$,初始速度为1,你可以用1的代价使速度-1,要求最小化代价通过所有铁轨,通过的顺序任意安排
-
Subtask3:判断代价是否为0,对每个速度建一个点,初始速度为0,最终速度为INF,铁轨看作边,中间点补上向速度+1的边,判断0到INF是否联通
-
欧拉路径
-
100分,还用刚才的模型,现在可以用1的代价添加一条i到i-1的边,现在唯一的问题是不联通
现在可以用一定的代价使i到i+1联通(离散化之后),最终的目标是是整个图联通,由于中间是欧拉路径,等价于一个无向图,这是什么东西?MST!
D1T3
一条链,每个点上额外挂一个点,每条边有权,在两个链上的点之间加一条边长为c,要求最小化两点间最短距离的最大值
- 二分答案,分类讨论两点与边两端的位置关系,转化为对边两端的位置限制,two pointers搞一搞,枚举限制关系可过3000
- 求限制关系的时候可以枚举j,线段树询问i,可过300000
- two pointer优化寻找i,j限制,可A
D2T1
一个长为n黑白串,给出一些位置的颜色,并且顺序给出所有k段极大连续黑色的长度,问哪些位置的颜色可以确定
- O(nk) DP,判断每个位置是否能为黑/白,
- 白色很好判断,扫一遍
- 黑色的话,穷举k,前缀和打标记,开始+1末尾-1
D2T2
交互题,有个机器,支持输入一个长度为n的01串,查询是否存在一个长度为n的01串,这个机器会把你输入的01串按照一个排列$ p_{1}p_{2}p_{3}p_{4}p_{5}...p_{n}$重排,求这个排列
- 分治,每次把区间二分,对左半区间内每个数i,构造一个数第i位为1,这个区间内其他数为0,区间外的数为1
- 复杂度$ nlog_2{n}$
D2T3
一个大正方形中有一些点,要求用不超过k个小正方形覆盖这些点,小正方形的对角线必须在大正方形对角线上,最小化小正方形面积并
-
不妨把左下的关键点翻折到右上,并把无用的点删除,则每个正方形会覆盖一段连续的点,考虑dp,直接转移是$ kn^2$,满足决策单调性,斜率优化得kn
-
这种选取不超过k的dp,如果dp[n][k]是一个关于k的凸函数,可以用二分一个斜率去切这个函数,直到切点为k时即为答案,
这里可以二分每个小正方形的代价c,用c去切每个dp位置,最终复杂度为$ nlog_2{nk}$
BM算法
- 口音太重,啥都听不懂
感想
- 冬眠营,掉线营
- 听个头啊
- 怎么口音这么重