【數學思維】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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章