k-size字符串(组合数学)
思路:因为要分成 段,显然字符 与字符 的段数绝对值值差
设 分成 段,即:
.
显然当 为偶数时,只有 这种情况。
即 或
在 个位置放置相应的一个字符 或 。
接下来就等价于将 个数放入 个格子的方式.
也等价于 整数 分成 个非负整数的方式。
令 为整数x分成 个非负整数的方式。
有 (这里 是保证第一个格子有数,不是第一个格子只放一个1)
即对应第一个数为0和第一个数不为0之和或者说是第一个格子不放东西和第一个格子放东西的方式之和。
根据观察这是一个组合数的递推:
根据 ,
所以可得
最后奇,偶数讨论一下即可得出答案。
需要注意的可能存在组合数的分母或分子 的情况要舍去。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
ll ksm(ll a,ll n){
ll ans=1;
while(n){
if(n&1) ans=ans*a%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
ll inv(ll x){
return ksm(x,mod-2);
}
ll C(ll x,ll y){
ll ans=1;
for(int i=1;i<=y;i++) ans=ans*(x-i+1)%mod*inv(i)%mod;
return ans;
}
ll f(ll x,ll y){
if(y<=0||x<0) return 0;
return C(x+y-1,x);
}
int main(){
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
if(k&1){
printf("%lld\n",(f(n-k/2-1,k/2+1)*f(m-k/2,k/2)%mod+f(n-k/2,k/2)*f(m-k/2-1,k/2+1)%mod)%mod);
}
else printf("%lld\n",2*f(n-k/2,k/2)*f(m-k/2,k/2)%mod);
return 0;
}