【数学思维】codeforces1084E The Fair Nut and Strings

E. The Fair Nut and Strings
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Recently, the Fair Nut has written k strings of length n, consisting of letters “a” and “b”. He calculated c — the number of strings that are prefixes of at least one of the written strings. Every string was counted only one time.

Then, he lost his sheet with strings. He remembers that all written strings were lexicographically not smaller than string s and not bigger than string t. He is interested: what is the maximum value of c that he could get.

A string a is lexicographically smaller than a string b if and only if one of the following holds:

a is a prefix of b, but a≠b;
in the first position where a and b differ, the string a has a letter that appears earlier in the alphabet than the corresponding letter in b.
Input
The first line contains two integers n and k (1≤n≤5⋅105, 1≤k≤109).

The second line contains a string s (|s|=n) — the string consisting of letters “a” and "b.

The third line contains a string t (|t|=n) — the string consisting of letters “a” and "b.

It is guaranteed that string s is lexicographically not bigger than t.

Output
Print one number — maximal value of c.


  题意是在所有长度为n的,字典序介于s和t逐渐的,只有由a,b组成的字符串中,选取k个,然后让它们前缀组成的集合最大。
  我们如果把字符二叉树画出来,一个字符串对应根到叶子的一条路径,就可以发现规律。如果某一层的节点数比k小,那么这一层的节点都可以被经过,反之,可以经过k个节点。从根到叶子逐一分配,就可以发现这样是完全可以实现的。因此代码很简单,就照做呗。

#include<cstdio>
#include<algorithm>
using namespace std;
using LL=long long;

char a[500005],b[500005];
int n,k;
LL cnt,ans;

int main()
{
	scanf("%d%d%s%s",&n,&k,a+1,b+1);
	cnt=1;
	for(int i=1;i<=n;i++)
	{
		cnt*=2;  //cnt记录每一层的总数
		if(a[i]=='b')
			cnt--;
		if(b[i]=='a')
			cnt--;
		if(cnt>1E9)
			cnt=1E9; //太多了就不用再算啦
		ans+=min(cnt,(LL)k);
	}
	printf("%lld",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/BUAA_Alchemist/article/details/85058945