zoukankan      html  css  js  c++  java
  • jzoj6300. Count

    Time Limits: 1000 ms Memory Limits: 524288 KB

    Description

    在这里插入图片描述

    Input

    在这里插入图片描述

    Output

    在这里插入图片描述

    Sample Input

    5 3 3

    Sample Output

    3

    Data Constraint

    在这里插入图片描述

    赛时

    比赛时一开始只想到30分。
    后来突然发现那个k似乎很小。
    那么就考虑把每个a都分解成m*p+q的形式。
    后者利用DP,前者利用组合数来求一求即可。
    然而似乎我打错了,而且时间复杂度估计错误,只拿了30分。(本来能多20分的啊)

    题解

    上面50分的做法一目了然。
    细细来讲就是:
    (A=sum q)
    那么当(A\%m==n\%m)时,就代表可以对答案造成贡献。
    由于每个a都是由若干个m相加最后加上个q形成。
    由于q的答案利用DP已经求出来了,接下来考虑如何分配这若干个m。
    当然组合数(挡板问题)
    由于(frac n m)巨大无比,但是k却奇小无比。
    怎么办?考虑直接把那个组合数计算的柿子上下约分即可。

    接下来考虑优化。
    我们看到DP似乎有点没用,那么考虑再利用组合数来代替DP。
    我们发现,这个不能直接套组合数,由于有些a可能分配到了比m-1大的数,所以我们要把这部分的答案容斥一下。
    注意小细节即可。

    标程

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const long long mo=998244353;
    
    long long n,m,ny2,ans,my,ii,kk,x;
    long long t,y,a,b,k,gs;
    long long zs[10000];
    bool bz[10000];
    long long jc[10000001];
    
    __attribute__((optimize("-O3")))
    long long qsm(long long a,long long b)
    {
    	long long t=1;
    	long long y=a;
    	while (b>0)
    	{
    		if (b%2==1) t=t*y%mo;
    		y=y*y%mo;
    		b=b/2;
    	}
    	return t;
    }
    __attribute__((optimize("-O3")))
    int main()
    {
    	freopen("count.in","r",stdin);
    	freopen("count.out","w",stdout);
    	scanf("%lld%lld%d",&n,&m,&k);
    	jc[0]=1;
    	for (int i=1;i<=10000000;i++)
    	{
    		jc[i]=jc[i-1]*i%mo;
    	}
    	ny2=qsm(2,mo-2);
    	for (long long i=1;i<=(m-1)*k;i++)
    	{
    		if (i%m==n%m)
    		{
    			long long j=(n/m-i/m);
    			my=(jc[i-1]*qsm(jc[k-1]*jc[i-k]%mo,mo-2)%mo);
    			x=-1;
    			for (long long now=1;now<=k-1;now++)
    			{
    				ii=i-now*(m-1);
    				if (ii<=0) break;
    				kk=(jc[k]*qsm(jc[now]*jc[k-now]%mo,mo-2)%mo)*(jc[ii-1]*qsm(jc[k-1]*jc[ii-k]%mo,mo-2)%mo)%mo;
    				my=(my+x*kk+mo)%mo;
    				x=x*(-1);
    			}
    			if (j==0)
    			{
    				ans+=my;
    				continue;
    			}
    			long long op=1;
    			for (long long l=1;l<=k-1;l++)
    			{
    				op=(op*(l%mo))%mo;
    			}
    			long long oq=1;
    			for (long long l=j+1;l<=j+k-1;l++)
    			{
    				oq=(oq*(l%mo))%mo;
    			}
    			op=qsm(op,mo-2);
    			op=op*oq%mo;
    			if (k==1)
    			{
    				op=1;
    			}
    			ans=(ans+(op*my)%mo)%mo;
    		}
    	}
    	printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    小于65535的数字编码(端口验证)
    js利用 iframe 或 a 标签连接下载文件
    vue 强制更新局部dom
    vue中js里的/* eslint-disable*/及其ESLint的介绍
    css取消双击选中文字
    Number.EPSILON
    js判断对象是否为空对象的几种方法
    python实现批量城市经纬度查询
    python基础知识之状态的储存和调用(即json和pickle)
    python基础知识之内置函数
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11350378.html
Copyright © 2011-2022 走看看