列表

详情


NC205049. k-size字符串

描述

牛妹最近在研究k-size字符串。
一个字符串为k-size指,字符串的连续段共有 个。所谓连续段指尽可能多的相同连续字母组成的子串。
例如:aabbbccc为3-size,因为('aa' 'bb' 'ccc'),ababaab为6-size,因为 ('a' 'b' 'a' 'b' 'aa' 'b')。
牛妹想知道,由 个 'a' 字符, 个 'b' 字符,组成长度为 的k-size字符串,共有多少种组成方式?由于该数可能过大,请对 取模。

输入描述

三个正整数  ,用空格隔开。

输出描述

一个正整数,为方案数对  取模的结果。

示例1

输入:

2 2 2

输出:

2

说明:

2\ 个 'a' 和 2\ 个 'b' 组成的字符串中,只有"aabb"和"bbaa"这两个是2-size,故输出 2\

示例2

输入:

1 2 3

输出:

1

说明:

1\ 个 'a' 和 2\ 个 'b' 组成的字符串中,只有"bab"是3-size,故输出 1\

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 27ms, 内存消耗: 616K, 提交时间: 2020-05-20 08:30:53

#include<iostream>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
ll qp(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}
ll inv(ll b)
{
	return qp(b,mod-2);
}
ll C(ll n,ll m)
{
	ll ans=1;
	if(m>n)return 0;
	for(ll i=1;i<=m;i++)
	ans=ans*inv(i)%mod*(n-i+1)%mod;
	return ans;
}
int main()
{
	ll n,m,k,ans=0;
	cin>>n>>m>>k;
	if(k>n+m||k==1)cout<<0;
	else
	{
		k-=2;
		ans=(ans+C(n-1,k/2)*C(m-1,k-k/2))%mod;
		ans=(ans+C(m-1,k/2)*C(n-1,k-k/2))%mod;
		cout<<ans;
	}
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 45ms, 内存消耗: 472K, 提交时间: 2020-05-19 14:51:34

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
ll inv(ll b){
	ll res=1,l=mod-2;
	for(;l;l>>=1,b=b*b%mod)
		if(l&1)res=res*b%mod;
	return res;
}
ll C(int a,int b){
	ll t=1;
	for(int i=1;i<=b;++i)t=t*(a-i+1)%mod*inv(i)%mod;
	return t;
}
ll f(int a,int b){
	if(a<=0||b<0)return 0;
	return C(a+b-1,b);
}
int main(){
	int n,m,k;
	scanf("%d%d%d",&n,&m,&k);
	if(k&1)
		printf("%lld",(f(k/2+1,n-k/2-1)*f(k/2,m-k/2)+f(k/2,n-k/2)*f(k/2+1,m-k/2-1))%mod);
	else printf("%lld",2*f(k/2,n-k/2)*f(k/2,m-k/2)%mod);
} 

上一题