[NOIP simulation test]: urban (city) (+ combinatorics inclusion and exclusion)

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++

Guess you like

Origin www.cnblogs.com/wzc521/p/11329755.html