[LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询问会给定一个长度为 \(k\) 的字符串 \(w\) 以及一对 \(L,R\), 求所有满足 \(i\in [L,R]\) 的 \(w[l_i:r_i]\) 在 \(s\) 中的出现次数之和. \(n,m,k,q\le 1\times 10^5\), \(\sum |w|\le 1\times 10…
loj 注意到每次询问串长度都是给定的,并且询问串长\(k*\)询问次数\(q<10^5\),所以这里面一个东西大的时候另一个东西就小,那么考虑对较小的下功夫 如果\(k\le \sqrt{n}\),那么可以\(O(k^2)\)暴力枚举询问串的每一个子串,然后在\(S\)的sam找到这个子串对应的点,算出出现次数,并且乘上在区间\([a,b]\)中这个子串询问的出现次数.找到子串对应的点为了方便,可以依次让询问串的某个前缀在sam上匹配,然后按长度从大到小枚举前缀的后缀,从匹配位置开始倍增跳父亲…
题意 链接 Sol \(10^5\)次询问每次询问\(10^5\)个区间..这种题第一感觉就是根号/数据分治的模型. \(K\)是个定值这个很关键. 考虑\(K\)比较小的情况,可以直接暴力建SAM,\(n^2\)枚举\(w\)的子串算出现次数.询问用个\(n^2\)的vector记录一下每次在vector里二分就好. \(K\)比较大的情况我没想到什么好的做法,网上的做法复杂度也不是很好.. 然后写了个广义SAM + 暴力跳parent就过了.. 不过这题思想还是很好的 #include<bi…
[LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解输出 -1. \(n \le 1000\). 题解 首先手玩下样例就可以发现一个非常虾皮的明显性质: 因为操作是赋值而不是取或, 于是一定是先让某一行都为 1 然后用这一行去染所有不是全 1 的列. 对于构造一个全 1 的行, 如果行号为 \(k\), 那么显然是用某一行的第 \(k\) 列上的 1…
[LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l r c 给 \([l,r]\) 区间内的值全部加上 \(c\). 2 l r d 给 \([l,r]\) 区间内的值全部除以 \(d\), 向下取整. 3 l r 求 \([l,r]\) 区间内的最小值. 4 l r 求 \([l,r]\) 区间内的值之和. \(n,q\le 1\times 10…
题意 链接 Sol 自己都不知道自己怎么做出来的系列 不难观察出几个性质: 最优策略一定是先把某一行弄黑,然后再用这一行去覆盖不是全黑的列 无解当且仅当无黑色.否则第一个黑色所在的行\(i\)可以先把第\(i\)列弄出一个黑色,接下来第\(i\)列的黑色可以把第\(i\)行全部弄成黑色. 然后直接算出把每一行弄黑的步数取个min就行了. 代码里面有注释. #include<bits/stdc++.h> #define Pair pair<int, int> #define MP(x…
题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的. 简单的证明一下:如果没有加的话,每个节点会被除至多log次, 总会除4nlogn次,每次区间加会恢复log个点的势能函数,这样总递归次数就是\(nlog^2n\). 下传标记的时候别忘了把min和max都更新一下 #include<bits/stdc++.h> #define Pair pai…
题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商贩的商品有一个价格\(a_i\),有两种政令: \(l, r, c\),对于\(i \in [l, r], a_i \leftarrow a_i + c\) \(l, r, d\),对于\(i \in [l, r], a_i \leftarrow \lfloor {a_i}/{d} \rfloor\…
LOJ 注意到\(qk \leq 10^5\),我们很不自然地考虑根号分治: 当\(k > \sqrt{10^5}\),此时\(q\)比较小,与\(qm\)相关的算法比较适合.对串\(s\)建SAM,考虑每组询问,将其所有的\((a,b)\)按照\(b\)从小到大排序,然后把\(w\)在\(s\)的SAM上匹配,每当右端点变为\(b\)的时候倍增跳到串\(s[a:b]\)的位置查询endpos即可. 当\(q > \sqrt{10^5}\),此时\(k\)比较小,与\(k^2\)相关的算法比较…
题目传送门:-> 看到题目的第一反应当然是暴力:对于串s建后缀自动机,每次询问中,求w对应的子串在s的SAM中的right集合.O(qmk)听上去显然过不了. 数据范围有个∑w<=1e5,也就是说,q*k<=1e5,当q更小或k更小时可以用不同的方法. k更小时,会发现每个w的子串数可能会很小,子串数可能还没m多.这个时候将m个[li,ri]的询问可能会有重复的,所以可以用vector存一下对于每一个[L,R],满足li=L且ri=R的询问的编号是哪些.求出w对于每个[L,R]有多少个满…