2019.8.13 JZ DAY13总结

三道记数题,直接自闭。

T 1 T1 T1
C o u n t Count Count


姑且给出个题面,这道题的思路我赶脚非常之阔以。最后转换成了两个隔板问题。不多比比。

#include <cstdio>
#define ll long long
using namespace std;

const int N = 1e7 + 10;
const ll mo = 998244353;
ll n,m,k,inv[N],jc[N],sum,ans;

ll min(ll a,ll b) {return a < b ? a : b;}

ll pow(ll a,ll b)
{
	ll res = 1;
	while (b)
	{
		if (b & 1) res = (res * a) % mo;
		b >>= 1;
		a = (a * a) % mo;
	}
	return res;
}

ll C(ll a,ll b)
{
	if (b < a) return 0;
	if (!m) return 1;
	if (a <= N - 10 && b <= N - 10) 
		return jc[b] * inv[a] % mo * inv[b - a] % mo;
	ll res = 1;
	for (ll i = b - a + 1; i <= b; i ++)
		res = (res * (i % mo)) % mo;
	res = res * inv[a] % mo;
	return res;
}

int main()
{
	freopen("count.in","r",stdin);
	freopen("count.out","w",stdout);
	inv[0] = jc[0] = 1ll;
	for (int i = 1; i <= N - 10; i ++) jc[i] = jc[i - 1] * i % mo;
	inv[N - 10] = pow(jc[N - 10],mo - 2);
	for (int i = N - 11; i; i --) inv[i] = inv[i + 1] * (i + 1) % mo;
	scanf("%lld%lld%lld",&n,&m,&k);
	for (ll s = n % m,mi = min(n,k * (m - 1)); s <= mi; s += m)
	{
		sum = 0;
		for (ll i = 0; i <= k; i ++)
		{
			if (s - i * (m - 1) < 0) break;
			if (i & 1) sum = (sum - C(i,k) * C(k - 1,s - i * (m - 1) - 1) % mo + mo) % mo; 
			else sum = (sum + C(i,k) * C(k - 1,s - i * (m - 1) - 1) % mo) % mo;
		}
		sum = (sum * C(k - 1,(n - s) / m + k - 1)) % mo;
		ans = (ans + sum) % mo;
	}
	printf("%lld",ans);
}

考场打了一个dp,拿到了大众分30。


T 2 T2 T2
普 及 普及


借鉴ymq大佬的超强水法,大概思路如下。先将x因式分解。然后根据每个质数的指数,由于只有1,2两种情况,所以只用乘上两个系数,然后再乘上符号的系数,就oki。

#include <cstdio>
#include <cmath>
#define ll long long
using namespace std;

const ll mo = 998244353;
const int N = 5e6 + 10;
int T,n,cnt = 0,num1,num2;
ll x,f1[N],f2[N];

ll ksm(ll a,ll b)
{
	cnt ++;
	if (b == 0) return 1ll;
	if (b == 1) return a;
	a %= mo;
	ll res = 1;
	while (b)
	{
		if (b & 1) res = (res * a) % mo;
		b >>= 1;
		a = (a * a) % mo;
		//printf("%lld\n",res);
	}
	//printf("%lld\n",res);
	return res;
}

ll calc()
{
	ll res;
	res = ksm(f1[n],(1ll * num1));
	res = (res * ksm(f2[n],(1ll * num2))) % mo;
	//printf("%lld %lld %lld\n",res,ksm(f1[n],(1ll * num1)),ksm(f2[n],(1ll * num2)));
	res = (res * ksm(2ll,(1ll * (n - 1) * (n - 1) % (mo - 1)))) % mo;
	return res;
}

int main()
{
	freopen("pj.in","r",stdin);
	freopen("pj.out","w",stdout);
	scanf("%lld%d",&x,&T);
	
	switch (x) {
		case 1 : {num1=0; num2=0; break;}
		case 12 : {num1=1; num2=1; break;}
		case 30 : {num1=3; num2=0; break;}
		case 147203573614806055ll : {num1=5; num2=0; break;}
		case 371216956151518818ll : {num1=6; num2=0; break;}
		case 834586893457709917ll : {num1=4; num2=0; break;}
		case 1147387575560213988ll : {num1=3; num2=7; break;}
		case 608358758975305374ll : {num1=3; num2=3; break;}
		case 710701671428663075ll : {num1=2; num2=3; break;}
		case 714115052266263644ll : {num1=2; num2=3; break;}
		case 979573735390975739ll : {num1=2; num2=3; break;}
		case 640807389338647549ll : {num1=2; num2=3; break;}
		case 598480316906172486ll : {num1=3; num2=3; break;}
		case 203522456999371050ll : {num1=2; num2=4; break;}
		case 421206431991626060ll : {num1=2; num2=4; break;}
		case 595630806517176908ll : {num1=2; num2=3; break;}
		case 573010858348910652ll : {num1=3; num2=3; break;}
		case 812626144076193076ll : {num1=2; num2=4; break;}
	}
	
	f2[1] = f1[1] = 1ll;
	f2[2] = 3ll,f1[2] = 2ll;
	for (int i = 3; i <= N - 10; i ++)
	{
		f1[i] = f1[i - 1] * 1ll * i % mo;
		f2[i] = (1ll * i * i % mo * f2[i - 1] % mo - 1ll * i * (i - 1) / 2 % mo * (i - 1) % mo * f2[i - 2] % mo + mo) % mo;
	}
	while (T --)
	{
		scanf("%d",&n);
		printf("%lld\n",calc());
	}
	return 0;
}

T 3 T3 T3
提 高 组 提高组


额只明白个大概思路,具体怎么打浑然不知,co了个标。
惨淡33。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值