Luogu U696097 有趣的点名 题解
2026.6.27 注 : 解法和解法证明来自豆包 AI , 本题解的所有文本、代码由本人编写 , 所有图片由本人制作 .
分析
设字符串 \(S\) 中的某一段由字符串 \(S_a\) , \(S_b\) , \(S_c\) 拼接而成 .
如图所示 :

图中蓝色矩形部分表示一个字符串首尾部的 " B " 连续段 , 绿色矩形部分表示一个字符串中部的 " B " 连续段 , 红色矩形部分表示一个字符串尾部的 " B " 连续段与后一个字符串首部的 " B " 连续段拼接而成的 " B " 连续段 .
绿色矩形部分对答案的贡献与字符串排列方式无关 , 而红色矩形部分对答案的贡献与字符串排列方式有关 .
设字符串 \(S_a\) 尾部的 " B " 连续段长度为 \(A\) , 字符串 \(S_b\) 首部的 " B " 连续段长度为 \(B\) , 则图中靠左的红色矩形部分对答案的贡献为 \(\lfloor \frac{A+B}{2} \rfloor\) . 同理可推得其他红色矩形部分对答案的贡献 .
在此有恒等式
\(\{x\}\) 即 \(x\) 的小数部分 .
设字符串 \(S_i\) 首部的 " B " 连续段长度为 \(start_i\) , 尾部的 " B " 连续段长度为 \(end_i\) , 中部的 " B " 连续段长度为 \(mid_i\) , 则答案为 :
设该式第一项为常数 \(C\) , 第二项为变量 \(K\) . 当变量 \(K\) 最小时 , 答案最小 .
通过观察 , \(\{\frac{end_i}{2}\}\) , \(\{\frac{start_{i+1}}{2}\}\) ∈ \(\{0,0.5\}\) . 当两者均为 \(0.5\) 时 , 会对答案贡献 \(1\) , 所以应尽量减少此类组合 , 以使变量 \(K\) 最小 .
为方便表示 , 将 \(0.5\) 表示为 " I " , \(0\) 表示为 " O " .例如某个数对 \((\{\frac{start_i}{2}\} , \{\frac{end_i}{2}\})\) 为 \(\{0,0.5\}\) , 则其可表示为 OI .
设 OI 的数量为 \(cnt_{OI}\) , 其余可类推 .
定理 \(1\)
对于任意一种字符串排列方式 , 有 \(K \geq \max(0,cnt_{II}-cnt_{OO}-1)\) .
证明
一 . 当 \(cnt_{II} \gt 0\) 时
可以将排列分为三个部分考虑 .
$1 . $ II 连续段内
设排列中有 \(m\) 个 II 连续段 , 第 \(j\) 段有 \(num_j\) 个 II , 那么 \(\sum_{j=1}^{m} num_j=cnt_{II}\) .
第 \(j\) 段对 \(K\) 贡献 \(num_j-1\) , 那么 \(m\) 段对 \(K\) 贡献
$2 . $ II连续段间
若两段间没有 OO , 则两段间一定有 OI 或 IO , 此时至少有一对 I 和 I相邻 ( 可能为 OI IO 或 OI II 或 II IO ) , 并对 \(K\) 至少贡献 \(1\) .
若两段间含有至少一个 OO , 则两段间对 \(K\) 贡献的下界为 \(0\) .
排列中有 \(m-1\) 个间隔 , 设其中有 \(t\) 个间隔含有至少一个 OO , 则有 \(m-1-t\) 个间隔对 \(K\) 至少贡献 \(1\) , 此时对 K 贡献
$3 . $ 最左端 II 连续段的左侧与最右端 II 连续段的右侧
两侧对 \(K\) 的贡献一定非负 , 即
综上所述 ,
因为一个 OO 只被一个间隔或两侧包含 , 且一个含有 OO 的间隔或两侧至少含有一个 OO , 所以 \(t \leq cnt_{OO}\) , 将其代入 , 得
因为 \(K\) 一定非负 , 所以
二 . 当 \(cnt_{II}=0\) 时
此时 , \(cnt_{II}-cnt_{OO}-1 \lt 0\) , \(K_内=0\) , \(K_间=0\) , \(K_{两侧} \geq 0\) , 则 \(K \geq 0\) , 与定理 \(1\) 一致 .
证毕 .
定理 \(2\)
存在字符串排列方式,使得 \(K=\max(0 , cnt_{II}-cnt_{OO}-1)\) .
证明
一种构造方式如下 :
左侧放置所有 IO ; 中部按照 II OO 的顺序交替放置 ( 若两者中一者会先放完 , 则另一者连续放置 ) ; 右侧放置所有 OI .
上述构造方式中 , 仅在 OO 用尽 , 形成 II 连续段时 , 段内会对 \(K\) 有贡献 .
结合定理 \(1\) 的证明 , 段内对 \(K\) 贡献 \(cnt_{II}-m\) .
$1 . $ 当 \(cnt_{II}-1 \geq cnt_{OO}\) 时
此时每个 II 不能自成一段 , II 连续段数量 \(m=cnt_{OO}+1\) , 将其代入 , 得
$2 . $ 当 \(cnt_{II}-1 \lt cnt_{OO}\) 时
此时每个 II 能自成一段 , II 连续段数量 \(m=cnt_{II}\) , 将其代入 , 得
综上所述 , \(K=\max(0 , cnt_{II}-cnt_{OO}-1)\) .
证毕 .
结合定理 \(1\) 和定理 \(2\) , 可知答案为
其中各项均为定值 , 与字符串排列方式无关 .
该解法时间复杂度为 \(O(|S|)\) .
代码
#include <bits/stdc++.h>
using namespace std;
int n;
string S;
int cnt[2][2];
long long ans;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n;
for(int i=1;i<=n;++i) {
cin>>S;
int len=S.size(),l=0,r=len-1;
while(S[l]=='B') ++l;
while(S[r]=='B') --r;
ans+=l/2,ans+=(len-r-1)/2; // 求floor(start_i/2)和floor(end_i/2)
for(int j=l;j<=r;) {
while(j<=r&&S[j]!='B') ++j;
int tmp=j;
while(j<=r&&S[j]=='B') ++j;
ans+=(j-tmp)/2;
} // 求floor(mid_i/2)
++cnt[l%2][(len-r-1)%2]; // 记录四种类型的字符串数量
}
cout<<ans+max(0,cnt[1][1]-cnt[0][0]-1);
return 0;
}

浙公网安备 33010602011771号