NOI2016
-
首先一个很明确的方向就是对于每一个拆分的位置算贡献
-
也就是对于每个位置求出前面有多少个形如 AA 的子串,求出后面有多少形如 BB 的子串,答案就是所有位置两者相乘的和
-
而实际上前缀和后缀是一样的,无非是将子串翻转一下再做,所以考虑一种就可以了
-
一个暴力的做法就是 \(O(n^2)\) 用 Hash 判断,然而这样就有了 95 分了(多少有点随意了......),考虑最后的 5 分怎么拿
-
讲实话正解不是很好想,考虑枚举每一个 A 可能的长度,然后以 \(len,2*len,3*len,...\) 为关键点
-
那么 \(AA\) 一定会经过恰好两个相邻关键点
-
那么我们考虑对于两个关键点求贡献,求出 \(lcp(i,j),lcs(i,j)\) ,根据这个可以算出通过这两个关键点的 \(AA\) 的范围,对于这个范围整体 + 1,这个可以差分做
-
对于 \(lcp,lcs\) 考虑 SAM 的做法就是求 parent 树上的 lca 的深度,那么考虑用 ST 表求正串和反串的 parent 树的 lca
-
关键点对的数量是一个调和级数,所以总的复杂度是 \(O(n\log n)\)
总结
-
SAM
-
关键点的想法确实是很难想的,难怪 \(n^2\) 会给到 95 分,不过两者思想的差距确实还是很大的
-
考虑在 k 进制下的循环小数 \(\frac{x}{y}\) ,设 \(\{x\}\) 表示 \(x\) 的小数部分,设 \(l\) 为循环小数的长度
-
那么 \(\{\frac{x}{y}\times k^l\}=\{\frac{x}{y}\}\)
-
那么 \(\frac{x}{y}k^l-\lfloor \frac{x}{y}k^l \rfloor=\frac{x}{y}-\lfloor\frac{x}{y}\rfloor\)
-
那么 \(xk^l=x-y\times (\operatorname{int})\),那么 \(xk^l\equiv x\pmod y\)
-
那么 \(k^l\equiv 1\pmod y\),那么 \(k\equiv 1 \pmod y,\gcd(k,y)=1\)
-
那么其实就是要求 :
\[\sum_{i=1}^n \sum_{j=1}^m [\gcd(i,j)=1][\gcd(j,k)=1] \] -
下面就是开始推式子了
- 那么第一层确定为数论分块了
- 设 \(f(n)=\sum_{i=1}^n [(i,k)=1]\),这个拿 \(\mu\) 反演一下就是 \(\sum_{d|k} \mu(d)\frac{n}{d}\) ,这一部分的复杂度就是 \(O(k的约数个数)\)
- 设 \(g(n,k)=\sum_{i=1}^n \mu(i)[(i,k)=1]\)
- 考虑将最后的一个式子拆开,注意到如果 \(\gcd(i,d)\neq 1\) ,那么 \(\mu(id)=0\)
-
边界为 \(g(0,k)=0,g(n,1)=\sum_{d|n} \mu(d)\) ,这个就直接杜教筛
-
事实上这个东西的复杂度在于杜教筛,所以为 \(O(n^{\frac{2}{3}})\)
-
总的复杂度就是 \(O((k的约数个数)\sqrt n+n^{\frac{2}{3}})\)