Topic Portal (internal question 8)
Input Format
Row of three integers $ n, m, k $.
Output Format
A row of integer answer. To $ 998,244,353 $ modulo.
Sample
Sample input
3 7 3
Sample Output
6
Data range and tips
For 10% of the data, $ 1 \ leqslant n, m , k \ leqslant 10 $.
For 40% of the data, $ 1 \ leqslant n, m , k \ leqslant 1,000 $.
For 70% of the data, $ 1 \ leqslant n, m , k \ leqslant {10} ^ 5 $.
To 100% of the data, $ 1 \ leqslant n \ leqslant {10} ^ 9 $, $ 1 \ leqslant n, k \ leqslant {10} ^ 7 $.
answer
$ 20% $ algorithm:
If $ n> m $ or $ n <m \ times k $ must then no program, direct $ puts ( "0"); $ to.
Time complexity: $ \ Theta (1) $.
Desired points: $ 0 $ points.
The actual points: $ 20 $ points.
$ 10% $ algorithm:
Explosive search, you can enumerate all cases.
Time complexity: $ \ Theta (n ^ k) $.
Desired points: $ 10 $ points.
The actual points: $ 10 $ points.
$ 40% $ algorithm:
Consider $ DP $, provided $ dp [i] [j] $ is the $ i $ the first cities, a share of the number of program $ j $ a construction team.
It might be listed state transition equation: $ dp [i] [j] = \ sum \ limits_ {k = 1} ^ {\ min (k, m)} dp [i-1] [jk] $.
Time complexity: $ \ Theta (n ^ 3) $.
Desired points: $ 40 $ points.
The actual points: $ 40 $ points.
$ 100% $ algorithm:
Inclusion and exclusion consideration, shutter method.
This problem can be transformed into the insertion $ n-1 $ m $ $ baffles in one article, the baffle can not be inserted together, the number of programs is $ C_ {m-1} ^ {n-1} $.
Now need to subtract the number of illegal schemes, provided with at least $ i $ cities is not legitimate, then the program number is $ C_n ^ i \ times C_ {mi \ times k-1} ^ {n-1} $, can be understood It is, that I first $ i \ times k $ th illegal to throw away, you can legally re-election in $ mi \ times k $ inside.
Use inclusion and exclusion statistics can answer.
Time complexity: $ \ Theta (m) $.
Desired points: $ 100 $ points.
The actual sub-: $ 100 $ points.
Code time
$ 20% $ algorithm:
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
int main()
{
scanf("%d%d%d",&n,&m,&k);
if(n>m||n*k<m)puts("0");
return 0;
}
$ 40% $ algorithm:
#include<bits/stdc++.h>
using namespace std;
int dp[7000][7000];
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)dp[1][i]=1;
for(int i=2;i<=n;i++)
for(int j=i;j<=m;j++)
for(int l=1;l<=min(k,m);l++)
dp[i][j]=(dp[i][j]+dp[i-1][j-l])%998244353;
cout<<dp[n][m]<<endl;
return 0;
}
$100%$算法:
#include<bits/stdc++.h>
using namespace std;
long long n,m,k;
long long jc[100000001],qsm[100000001];
long long ans;
long long qpow(long long x,long long y)
{
long long res=1;
while(y)
{
if(y&1)res=res*x%998244353;
x=x*x%998244353;
y>>=1;
}
return res;
}
void pre_work()
{
jc[0]=1;
for(int i=1;i<=m;i++)
jc[i]=1LL*jc[i-1]*i%998244353;
for(int i=0;i<=m;i++)
qsm[i]=qpow(jc[i],998244351)%998244353;
}
long long cm(long long x,long long y)
{
return jc[x]*qsm[y]%998244353*qsm[x-y]%998244353;
}
long long lucas(long long x,long long y)
{
if(!y)return 1;
return cm(x%998244353,y%998244353)*lucas(x/998244353,y/998244353)%998244353;
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&k);
if(n>m||n*k<m){puts("0");return 0;}
pre_work();
long long flag=-1;
ans=jc[m-1]*qsm[n-1]%998244353*qsm[m-n]%998244353;
for(int i=1;i<=n;i++)
{
if(m-i*k<n)continue;
ans=(ans+flag*lucas(n,i)%998244353*lucas(m-i*k-1,n-1)+998244353)%998244353;
flag=-flag;
}
printf("%lld",(ans+998244353)%998244353);
return 0;
}
rp++