https://codeforces.com/problemset/problem/1083/B
题目大意:给两个长度为n(len<=5e5)的只含有a和b的串S和串T,S<=T
于是存在字符串p使得S<=p<=T,从中任意选出k(k<=5e5)个字符串p
于是存在字符串s,使得s是k个字符串p之一的前缀
求有策略地选择k个字符串p,可使得符合条件的s数量最大的最大数量。
嗯~~~,刚开始想呀想,这种编码的东西真是不会呀。
后来看到cf上大神的超简单的代码(后面会给出),震惊了,
看半天终于看懂了,这样理解,以下的例子是S="aaa",T="bab"
这样的一棵树大家应该还是看得懂,字符串S和T就这样表示出来了
那么对于可行的字符串p,就是从S和T表示的路径的中间区域,向下走就可以了,走白色的点或者绿色的点
都OK,那么从图中可以看出,绿色的点有6个,白色的点(除根节点)有5个,因此字符串p的选择也有(6+5)=11个
接下来看到要求的答案,由于字符串p最多只能选择k个,并且由于如果A和B都可作字符串p,A是B的前缀,则B肯定不必A次
多以我们p的选择肯定是尽量长的。而当我们把k条p在树上用路径表示出来时,他们可获得的s数量也就是这些p中包含的结点数量。
知道了这些,接下来就是要遍历处理了
先看第一层,这一层的S,T子串是"a","b",这一层在两个绿点之间的白点数为rom=0,串p可以选择min(k,rom+2=2)个
下一层,S,T分别为“aa","ba",S和T的第二个字母都是'a',但白色节点还是增加了一个,所以rom固定要+1,p可以选择rom+2=3个
再下一层,上一层的白点分裂成了两个,由于S和T第三个字母分别是'a'和'b',白点又增加了1+1=2个,所以rom=rom*2+1+T[i]-S[i],这一层rom=4,p可选择min(k,rom+2=6)个
说了这么多,ans呢,ans我们也可以一层一层算,每一层可以是前缀的串s数量=min(k,rom+2)个
全部加起来ans就出来了
弄到树上好像的确简单好多了
/
while (++times, T--)
{
ll rom(0), ans(0);
string s1, s2;
ll n, k;
cin >>n>>k >> s1 >> s2;
RE(i, s1.length())
{
rom = 2*rom + s2[i] - s1[i];
rom = min(rom, k);
ans += min(rom+1,k);
}
cout << ans << endl;
}
///
return 0;