需要复制一段文字,具体来说给定一个字符串 si,然后你有一个剪贴板,初始为空,和一个初始为空的字符串 t,然后对于所有 1 到 n 的 i,小水母会依次进行如下操作:
- "Ctrl + C" 操作,将剪贴板的内容修改为 si。
- "Ctrl + V" 操作,将剪贴板的内容添加到 t 末尾。
每次 "Ctrl + C" 操作和 "Ctrl + V" 操作都只有一半概率成功。求最终串 t 的期望权值,其定义为多少个子串只有一种字符。Q 次单点修改 si,你需要输出每次修改后的答案。(n,Q<=2e5)
记得往简单了想。
对于一个字符,最好是求以每个位置结尾,向前最长连续段期望长度。
(强制结尾思想的完全运用。)
枚举这个字符。对于每个位置 i,要求它必须 Ctrl-V,此时剪贴板内字符显然必须为 si,这个概率①容易计算。
然后这个 byd 继承我解释不下去了。我这沟槽数学水平死路一条。
//NOI-MRA-3004 zhouziqi
//pw[i]:=2**i
//ipw[i]:=pw[i]**(-1)
void DP(char c, int op) {
for (int i = 1; i <= n; i ++) {
sum[i] = sum[i - 1];
if (s[i] == c) {
add(sum[i], pw[i - 1]);
}
}
for (int i = 1, s0 = 0, s1 = 0; i <= n; i ++) {
int f = ((long long){sum[i]} * ipw[i + 1] //①
+ ((long long){sum[i]} * s0 + s1) % P * ipw[i << 1]) % P;
if (op > 0) {
add(ans, f);
} else {
add(ans, P - f);
}
int mul = (long long){pw[i]} * f % P;
add(s0, mul);
add(s1, (long long){pw[i] - sum[i] + P} * mul % P);
}
}
钟声:线性 DP 不会时,不要拒绝暴力的想法!多一点小常数会赢的!
把选子串用组合意义解构,变成选 l,r。仍然枚举字符 ch,记 fi,0/1,0/1/2 表示到 i,剪贴板是否为 ch,lr 中选了多少个,期望选 lr 有多少种方案。
这转移只要看 i-1,容易多了!
矩阵乘法 125(因为第三维为 2 时第二维没用),线段树开 26 棵,会赢的!
参考转移:
S-NOIP-309 tangyiwen
每个字符单独算贡献,变成 01 串
f(i, 0/1):当前考虑了前 i 个字符,剪切板字符是 0/1 的概率
g(i, 0/1):左端点期望个数
h(i, 0/1):区间期望个数
a:=f(i,0)
b:=f(i,1)
c:=g(i,0)
d:=g(i,1)
s:=h(i,0)+h(i,1)
0 : [a, b, c, d, s] -> [
a * 4 + b * 2,
b * 2,
c * 2 + d,
d * 2 + b,
s * 4 + d + b
]
1 : [a, b, c, d, s] -> [
a * 2,
a * 2 + b * 4,
c,
a + c * 2 + b * 2 + d * 4,
s * 4 + a + c + b * 2 + d * 2
]
写成总方案数了。除 2**(2n) 就是答案。
初值 a=1,答案为 s。