【csp模拟赛5】限制 (restrict.cpp)--数学

自己看吧:

爆搜代码:

//春水初涨-春林初盛-春风十里-不如你
//----hzwer 
// 这是啥子题,读不懂-- 
//题意有问题 -- 
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cstdio>
#include<map>
#define mod 998244353
#define N 100000
using namespace std;
int n,m,s,y[N],sum[N],sumy;
int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
struct yelir
{
	int pos,sum;
	bool operator < (const yelir &a) const
	{
		if(pos==a.pos) return sum < a.sum;
		return pos < a.pos;
	}
};
map< yelir , int >mp;
int dfs(int pos,int sum)
{
	yelir x = yelir{ pos,sum };
	if(pos==n+1)
	{
		if(sum % m==s)return 1;
		return 0;
	}
	if(mp.find(x) != mp.end() )
	{
		return mp[x];
	}
	int ans=0;
	for(int i=0;i<=y[pos];++i)
	{
		ans+=dfs(pos+1,sum+i);
		ans%=mod;
	}
	mp[x]=ans;
	return ans;
}
int main()
{
	#ifdef yilnr
	#else
	freopen("restrict.in","r",stdin);
	freopen("restrict.out","w",stdout);
	#endif
	n=read();s=read();m=read();
	for(int i=1;i<=n;++i)y[i]=read();
	printf("%d",dfs(0,0));
	fclose(stdin);fclose(stdout);
	return 0;
}
/*
5 145 100000
49 49 48 48 48
*/

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define mod 998244353
#define int long long
#define N 5000008
using namespace std;
int s, m, n, ans, sum, cnt, f, tmp,M;
int y[100005], c =1e9,jie[N],inv[N];
int invjc[N], jc[N];
int power(int x, int y)
{
	int res = 1;
	for(; y; y >>= 1, x = x %mod* x %mod)
	  if(y & 1) 
		res = res %mod* x%mod;
	return res%mod;
}
void init()
{
	jie[0] = jie[1] = inv[0] = inv[1] = 1;
	for(int i = 2;i <= 6000000;i ++)jie[i] = jie[i-1] * i % mod;
	inv[6000000] = power(jie[M],mod-2);
	for(int i = 60000000 - 1;i >= 2;i --)inv[i] = inv[i+1] * (i + 1) % mod;
}
int C (int n,int m) 
{
 	  if(n < 0 || m < 0 || n<m) return 0;
	  return jie[n] * inv[m] % mod * inv[n-m] % mod;
}
signed main()
{
	#ifdef yilnr
	#else
	freopen("restrict.in","r",stdin);
	freopen("restrict.out","w",stdout);
	#endif
    scanf("%lld%lld%lld",&n, &s, &M);
    for(int i = 1; i <= n; i++)
    {
    	scanf("%lld",&y[i]);
    	sum+=y[i];
    	c = min(c, y[i]);
    }
    int yi=0;
    init();
    for(int i=1;i<=n;i++) m+=(y[i]==c+1);
    for(int k=s;k<=sum;k+=M)
    {
    	for(int i=0;i<=n;i++)
    	{
    		int vis=0;
    		for(int j=0;j<=m;j++)
    		{
    			vis+= C( k-j-i*(c+1)+n-1 , n-1)%mod * C( m , j ) %mod * C( n-m , i-j)%mod;
    			vis%=mod;
    		}
    		if(i & 1) ans=(ans+mod-vis)%mod;
    		else ans=(ans+vis)%mod;
    	}
    }
    printf("%lld\n",ans);
	return 0;
}
/*
5 145 100000
49 49 48 48 48
*/

 ----WFX

猜你喜欢

转载自www.cnblogs.com/yelir/p/11564333.html