Note - Border Theory
经典结论,但是不太会就写一个博客。
结论
给定字符串 \(s\),其所有 Border 可以按二进制最高位划分为 \(\mathrm O(\log n)\) 个等差数列。
证明
下将字符串长度记为 \(n\)。
定义 \(i\) 为字符串 \(s\) 的 Border,当且仅当 \(\forall 1 \le p \le i, s_p = s_{n-i+p}\)。故 Border 又称公共前后缀。
定义 \(i\) 为字符串的周期,当且仅当 \(\forall 1 \le p \le n-i, s_p = s_{i+p}\)。
引理 1:若 \(i\) 是 \(s\) 的一个 Border,则 \(n-i\) 是 \(i\) 的一个周期。
证明:由于 \(i\) 是一个 Border,则 \(\forall 1 \le p \le i, s_p = s_{n-i+p}\),变形得 \(1 \le p \le n-(n-i), s_p = s_{p+(n-i)}\),发现与周期的定义形式相同。证毕。
引理 2(弱周期定理):若 \(p, q\) 都是 \(s\) 的周期,且 \(p+q \le n\),则 \(\gcd(p, q)\) 也是 \(s\) 的周期。
证明:不妨设 \(p > q\),考虑 \(i[1 \le i \le n-(p-q)]\)。
- 若 \(i \le n-p\),则由 \(p\) 为周期有 \(s_i = s_{i+p}\),由 \(q\) 为周期有 \(s_{i+p} = s_{i+p-q}\),联合上式得 \(s_{i} = s_{i+p-q}\)。
- 若 \(i > n-p\),由 \(p+q \le n\) 有 \(i > q\)。则仿照上式,有 \(s_{i} = s_{i-q}\) 且 \(s_{i-q} = s_{i-q+p}\),则有 \(s_{i} = s_{i+p-q}\)。
感性地,我们可以把下标左右移动 \(p\) 或者 \(q\),前提是不超出 \([1, n]\)。那么在给出的条件内,\(i+p-q\) 和 \(i-q+p\) 必有一个可行。
发现上过程实际上是辗转相减,于是证毕。
引理 2.5(强周期定理):若 \(p, q\) 都是 \(s\) 的周期,且 \(p+q-\gcd(p, q) \le n\),则 \(\gcd(p, q)\) 也是 \(s\) 的周期。
证明:Hootime 看了 2h,证明了自己不会证明。可以看这个。但是没关系反正后面用不着。
引理 3:对于所有 \(\ge \lfloor \frac n 2 \rfloor\) 的 Border,其与 \(n\) 组成等差数列。
若只有 \(0\) 或 \(1\) 个 \(\ge \lfloor \frac n 2 \rfloor\) 的 Border,定理显然成立。
考虑两个 \(\ge \lfloor \frac n 2 \rfloor\) 的 Border \(n-p, n-q\),由 引理 1 我们得到两个周期 \(p, q\)。又由 引理 2 我们得到 \(\gcd(p, q)\) 也是一个周期。
由于 \(n-p\) 是最大 Border,则 \(p\) 必然是最小周期,则 \(\gcd(p, q) = p\),也就是说 \(q\) 是 \(p\) 的倍数。推广到所有满足条件的 \(q\) 即得证。
对于结论,我们考虑 \([2^i, 2^{i+1})\),设其中最大的 Border 为 \(p_i\),显然其余的 Border 都是 \(s_{1 \sim p}\) 的 Border,由 引理 3 得其为等差数列。证毕。
例题
P4156 [WC2016] 论战捆竹竿
容易发现接在一起的一段必然是 Border。
假设我们不知道 Border Theory。我们发现可以对于每一个 Border \(i\),对于 \(n-i\) 跑同余最短路,但是 \(\mathrm O(n^2)\),视实现方式 \(30 \sim 50 \mathrm{pts}\)。
然而我们知道 Border Theory。
知道 Border Theory 我们就可以把 Border 拆解为 \(\log n\) 个等差数列,然后对于每个等差数列 \(a_i = a_0+ki\),我们以 \(a_0\) 为模数跑一遍同余最短路,使用单调队列求当前的最短长度即可。
接下来我们考虑如何把同余最短路的模数从 \(a\) 换成 \(b\)。我们可以把 \(a\) 中每个同余类的答案 \(dis_i\) 转移到 \(dis'_{dis_i \bmod b}\)。然而存在情况使得在 \(a\) 的剩余系中不优的距离在 \(b\) 的剩余系中最优。发现这些情况一定可以由 \(a\) 剩余系中最优的距离加上若干个 \(a\) 求得,于是我们再这么跑一遍同余最短路即可。
#include <bits/stdc++.h>
#define llong long long
#define N 500005
using namespace std;
int n; llong k;
char a[N];
int nxt[N], Log2[N];
basic_string<int> num[N];
llong dis[N], tmp[N], ans;
typedef pair<int, llong> Node;
Node que[N<<1]; int he, ta;
void _prework(){
for(int i = 2; i < N; ++i) Log2[i] = Log2[i>>1]+1;
}
void _init(){
for(int i = 0; i <= Log2[n]; ++i) num[i].clear();
ans = 0;
return;
}
int _main(){
scanf("%d %lld", &n, &k), k -= n;
scanf("%s", a+1);
if(k < 0){
puts("0");
return 0;
}
for(int i = 2; i <= n; ++i){
nxt[i] = nxt[i-1];
while(nxt[i] && a[nxt[i]+1] != a[i]) nxt[i] = nxt[nxt[i]];
if(a[nxt[i]+1] == a[i]) ++nxt[i];
}
int x = n;
while(x){
x = nxt[x];
num[Log2[x]].push_back(n-x);
}
for(int i = 1; i < N; ++i) dis[i] = (llong)1e18+3;
int lst = 1e9+7;
for(int i = 0; i <= Log2[n]; ++i){
if(!num[i].size()) continue;
int now = num[i][0], siz = num[i].size();
if(lst < 1e9){
for(int j = 0; j < now; ++j) tmp[j] = (llong)1e18+3;
for(int j = 0; j < lst; ++j)
tmp[dis[j]%now] = min(tmp[dis[j]%now], dis[j]);
int l = __gcd(now, lst), len = now/l;
for(int j = 0; j < l; ++j){
int pos1 = j, pos2 = j+lst;
for(llong k = 1; k <= len*2; ++k, pos1 = pos2, pos2 = pos2+lst){
while(pos2 > now) pos2 -= now;
tmp[pos2] = min(tmp[pos2], tmp[pos1]+lst);
}
}
for(int j = 0; j < now; ++j) dis[j] = tmp[j];
}
lst = now;
if(siz == 1) continue;
int d = num[i][1]-num[i][0];
int l = __gcd(now, d), len = now/l;
for(int j = 0; j < l; ++j){
que[he = ta = 1] = make_pair(j, 0);
int pos = j+d;
for(llong k = 1; k <= len*2; ++k, pos = pos+d){
while(pos > now) pos -= now;
while(he <= ta && que[he].second <= k-siz) ++he;
dis[pos] = min(dis[pos], dis[que[he].first]+now+(k-que[he].second)*d);
while(he <= ta && dis[que[ta].first]+(k-que[ta].second)*d >= dis[pos]) --ta;
que[++ta] = make_pair(pos, k);
}
}
}
for(int i = 0; i < lst; ++i)
if(dis[i] <= k) ans += (k-dis[i])/lst+1;
printf("%lld\n", ans);
return 0;
}
int T;
int main(){
scanf("%d", &T);
_prework();
while(T--) _init(), _main();
return 0;
}

浙公网安备 33010602011771号