# T1

#include<iostream>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<cstring>
using namespace std;
long long f[1005][1005],g[1005][1005];
int n,m,p,mod=1000000007;
int main()
{
freopen("pf.in","r",stdin);
freopen("pf.out","w",stdout);
int i,j;long long ans=0;
scanf("%d%d%d",&n,&m,&p);
if(n==m&&p>n){printf("0");return 0;}
g[1][0]=1;g[1][1]=1;
for(i=2;i<=n;i++){//杨辉三角求组合方法
g[i][0]=1;
for(j=1;j<=i;j++)
{g[i][j]=g[i-1][j]+g[i-1][j-1];g[i][j]%=mod;}
}
for(j=m;j<=n;j++){
f[j][1]=j;
for(i=2;i<=m;i++)
{f[j][i]=(long long)f[j][i-1]*(j-i+1);f[j][i]%=mod;}
for(i=max(m+1,2);i<=p;i++)//注意 m=0 的情况
{f[j][i]=(long long)f[j][i-1]*(j-m);f[j][i]%=mod;}
if(j!=n){ans=(long long)f[j][p]*g[n][j]-ans;if(ans<0)ans+=mod;ans%=mod;}//迷一般的容斥
}
ans=(long long)(f[n][p]+mod)-ans;ans%=mod;
printf("%lld",ans);
return 0;
}


# T2

#include<iostream>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<cstring>
using namespace std;
int q=0,w=1;char ch=' ';
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')q=q*10+ch-'0',ch=getchar();
return q*w;
}
double f[201][201][405],p[201];//前 i 场比赛赢 j 次背包为 k
int n,l,k,a[201];
int chan(int x){//溢出的就不用算了啦
if(x>n)x=n;
return x+201;
}
int main()
{
freopen("guard.in","r",stdin);
freopen("guard.out","w",stdout);
int i,j,t,x;double ans=0;
f[0][0][chan(k)]=1.0;
for(i=0;i<n;i++)
for(j=0;j<=i;j++)
for(t=-i;t<=n;t++){//因为不要溢出部分，所以要正向推
f[i+1][j+1][chan(t+a[i+1])]+=f[i][j][chan(t)]*p[i+1];
f[i+1][j][chan(t)]+=f[i][j][chan(t)]*(1.0-p[i+1]);
}
for(i=l;i<=n;i++)
for(j=0;j<=n;j++)ans+=f[n][i][chan(j)];
printf("%.6lf",ans);
return 0;
}


# T3

#include<iostream>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<cstring>
using namespace std;
int q=0;char ch=' ';
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')q=q*10+ch-'0',ch=getchar();
return q;
}
const int maxn=(1<<20);
int n,m;long long ans;
long long dp[22][maxn];
bool l[22][22];
int getmi(int x){//寻找路径上编号最小点
for(int i=0;i<n;i++)
if(x&(1<<i))return i;
}
int cnt(int x){//寻找经过了几个点
int re=0;
for(int i=0;i<n;i++)
if(x&(1<<i))re++;
return re;
}
int main()
{
freopen("hamilton.in","r",stdin);
freopen("hamilton.out","w",stdout);
int i,j,x,y,up,zt;
for(i=1;i<=m;i++){
l[x][y]=l[y][x]=1;
}
for(i=0;i<n;i++)dp[i][(1<<i)]=1;//if 遇到可以从 i 走到 i 的情况，那么说明找到了一个简单环
up=(1<<n)-1;
for(zt=1;zt<=up;zt++)
for(i=0;i<n;i++)
if(dp[i][zt]&&(zt&(1<<i))){
for(j=getmi(zt)+1;j<n;j++)
if(l[i][j]&&!(zt&(1<<j)))dp[j][zt|(1<<j)]+=dp[i][zt];
}
for(i=0;i<n;i++)
for(j=1;j<=up;j++)
if(l[i][getmi(j)]&&cnt(j)>2)ans+=dp[i][j];
printf("%lld",ans/2);
return 0;
}


# T4

#include<iostream>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<cstring>
using namespace std;
int q=0,w=1;char ch=' ';
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')q=q*10+ch-'0',ch=getchar();
return q*w;
}
long long a[100005],f[100005],que[100005],tot;
int ti[100005];
int n,m,l,r;
int main()
{
freopen("cg.in","r",stdin);
freopen("cg.out","w",stdout);
int i,j;long long ans=LLONG_MAX;
for(i=1;i<=n;i++){
f[i]=a[i]+que[l];
while(que[r]>f[i]&&l<r)r--;
que[++r]=f[i];ti[r]=i;
while(ti[l]<i-m)l++;//no = because 一定要剪掉这里
}
for(i=n-m;i<=n;i++)ans=min(ans,f[i]);
printf("%lld",tot-ans);
return 0;
}


%%% 董事长%%%