zoukankan      html  css  js  c++  java
  • UOJ #269. 【清华集训2016】如何优雅地求和

    话说这题今年ZJOI讲课的时候lyx好像讲过,但是以当时姿势水平的我显然是看不懂的,所以现在来回头补一下

    我们先来考虑一个简单的情况,(f(k)=k)时,我们可以得到:

    (Q=sum_{k=0}^n k imes C_n^k imes x^k imes (1-x)^{n-k})

    很显然为了化简后面的式子我们要凑出二项式定理的形式,同时这种推导在这里的P5591里已经推导过一遍了,就是用组合数吸收掉(k),因此最后就是(Q=nx)

    但我们发现这个形式不够一般,但却能给我们一定的启发:前面的系数除了是(k)还能不能是别的可以通过组合数来吸收呢?

    根据《具体数学》上的一些套路,我们发现下降阶乘幂有这个很好的性质,比如:我们令(f(k)=k^{underline d})时,则有:

    [Q=sum_{k=0}^n k^{underline d} imes C_n^k imes x^k imes (1-x)^{n-k} ]

    [=sum_{k=0}^n k^{underline d} imes frac{n!}{k!(n-k)!} imes x^k imes (1-x)^{n-k} ]

    [=sum_{k=0}^n n^{underline d}x^d imes frac{(n-d)!}{(k-d)!(n-k)!} imes x^{k-d} imes (1-x)^{n-k} ]

    [=n^{underline d}x^d imessum_{k=0}^n C_{n-d}^{k-d} imes x^{k-d} imes (1-x)^{n-k} ]

    所以后面还是一样的等于(1),因此这是(Q=n^{underline d} x^d)

    考虑最后答案的式子,我们显然发现对于(f(k)=sum_{i=0}^m a_i x^{underline i}),那么显然有(Q(f,n,x)=sum_{i=0}^m a_i imes Q(k^{underline i},n,x))

    根据前面的推导我们现在已经会做(Q)了,但是那个(a_i)该怎么求呢?

    我们考虑设(b_i=frac{a_i}{i!}),那么(f(k)=sum_{i=0}^m b_i imes C_x^i)

    考虑下降阶乘幂最好的朋友是谁,在《具体数学》中也有提到它就是差分(因为用来求不定和式的时候下降阶乘幂用处很大,而结合差分之后在离散数学中可以发挥和微积分类似的作用)

    我们考虑我们现在知道的是(k=0,1,cdots,m)(f(k))的值,首先有(k=0)(f(0)=b_0)

    然后我们记(Delta f(k)=f(k+1)-f(k)),即它的一阶差分,因为组合数的基本性质(C_{k+1}^i-C_k^i=C_k^{i-1}),我们发现此时(Delta f(k)=sum_{i=0}^m b_i imes C_k^{i-1}),那么显然此时有(Delta f(0)=b_1)

    同理,我们容易推导出(Delta^d f(0)=b_d),即(d)阶差分后(0)处的值为(b_d)

    那么我们现在可以直接写出一个(O(m^2))的暴力,再往后应该可以用NTT优化,但是由于这里数据范围不大,出题人写的也是(O(m^2)),因此我就懒了一下用暴力过了

    #include<cstdio>
    #define RI register int
    #define CI const int&
    using namespace std;
    const int N=20005,mod=998244353;
    int n,m,x,b[N],ans,ret=1,inv=1;
    inline void inc(int& x,CI y)
    {
    	if ((x+=y)>=mod) x-=mod;
    }
    inline int sub(CI x,CI y)
    {
    	int t=x-y; return t<0?t+mod:t;
    }
    inline int quick_pow(int x,int p=mod-2,int mul=1)
    {
    	for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
    }
    int main()
    {
    	RI i,j; for (scanf("%d%d%d",&n,&m,&x),i=0;i<=m;++i)
    	scanf("%d",&b[i]); for (i=0;i<=m;++i)
    	{
    		if (i) inv=1LL*inv*quick_pow(i)%mod;
    		inc(ans,1LL*ret*b[0]%mod*inv%mod);
    		for (j=0;j<m-i;++j) b[j]=sub(b[j+1],b[j]);
    		ret=1LL*ret*x%mod*(n-i)%mod;
    	}
    	return printf("%d",ans),0;
    }
    
  • 相关阅读:
    第3课 线性分类器损失函数与最优化
    李飞飞机器视觉课程笔记:第2课 K最近邻与线性分类器
    周志华《机器学习》第二章学习笔记
    通过anaconda安装tensorflow
    周志华《机器学习》第一章学习笔记 奥卡姆剃刀原理、没有免费的午餐定理(NFL)、回归模型
    DPM目标检测模型
    损失函数的理解
    mini-batch的理解
    前向传播、后向传播
    SVM(支持向量机)的理解
  • 原文地址:https://www.cnblogs.com/cjjsb/p/11828595.html
Copyright © 2011-2022 走看看