• 【模板】【刷题】差分与前缀和_LuoguP5488_多项式


    题面

    • 给定长度为(n)的序列(a),求其(k)阶差分和前缀和。
    • 对1004535809取模。
    • (1leq nleq 10^5, 1leq kleq 10^{2333})

    题解

    • 我们发现可以算原序列中每一位对于最终结果的贡献是多少。
    • 对于差分,我们记原序列中第(i)位上的数,对第(k)次差分之后的第(j)位的贡献为(Delta^ka_j(i))(这个记号没有任何学术依据,纯粹就是我在这里方便表达写出来的。)
    • 我们可以写出递推式:(Delta^ka_j(i)=Delta^{k-1}a_j(i)-Delta^{k-1}a_{j-1}(i))(注意到这道题的差分和我以前习惯的定义不太一样。)
    • 我们发现这是什么?这就是组合数啊。(只不过有个减号,但是你仔细品一品,会发现这根本不影响。)
    • 我们甚至可以获得一个组合意义:我们想象现在有个(k)(n)列的矩阵,你每次行走要么走到下一行后一列,系数乘(-1),要么走到下一行的这一列,系数乘(1)
    • 反正不管怎么样,我们就是获得了一个组合数的式子,(Delta^ka_j(i)=(-1)^{j-i}C_{k}^{j-i})
    • 接下来(Delta^ka_i=sumlimits_{j=0}^{k}a_{i-j}(-1)^jC_{k}^{j})。直接卷。
    • 前缀和也是差不多的思路。算贡献,也可以得到一个走矩阵的思路。
    • 我们有(k)行,每次可以向下走一步,或者向右下走一步。从第零行的第(i)列走到第(k)行的第(j)列的方案数就是(a_i)对那个数贡献了多少倍。
    • 我是真的菜,没见过什么前缀和的表示方法。就用(和^ka_i)来表示(k)阶的第(i)位吧。
    • (和^ka_i=sumlimits_{j=0}^{k}a_{i-j}C_{k}^{j})。直接卷。

    代码

    #include<bits/stdc++.h>
    #define LL long long
    #define MAXN 400000
    #define MOD 1004535809
    #define YG 3
    using namespace std;
    template<typename T>void Read(T &cn)
    {
    	char c; int sig = 1;
    	while(!isdigit(c = getchar())) if(c == '-') sig = -1; cn = c-48;
    	while(isdigit(c = getchar())) cn = cn*10+c-48; cn*=sig;
    }
    template<typename T>void Read_m(T &cn)
    {
    	char c; 
    	while(!isdigit(c = getchar())); cn = c-48;
    	while(isdigit(c = getchar())) cn = (cn*10ll+c-48)%MOD; 
    }
    template<typename T>void Write(T cn)
    {
    	if(cn < 0) {putchar('-'); cn = 0-cn; }
    	int wei = 0; T cm = 0; int cx = cn%10; cn/=10;
    	while(cn) wei++, cm = cm*10+cn%10, cn/=10;
    	while(wei--) putchar(cm%10+48), cm /= 10;
    	putchar(cx+48);
    }
    template<typename T>void Max(T &cn, T cm) {cn = cn < cm ? cm : cn; }
    template<typename T>void Min(T &cn, T cm) {cn = cn < cm ? cn : cm; }
    const int MAXNTT = MAXN*4+1;
    int n, k, typ;
    int a[MAXNTT], b[MAXNTT];
    int omg[MAXNTT], inv[MAXNTT], fan[MAXNTT], Mn;
    int erwei(int cn) {int guo = 0; while(cn) guo++, cn>>=1; return guo; }
    LL ksm(LL cn, LL cm) {LL ans = 1; cn=cn%MOD; while(cm) ans = ans*(1+(cn-1)*(cm&1))%MOD, cn = cn*cn%MOD, cm>>=1; return ans; }
    void yuchu(int cn)
    {
    	Mn = 1<<erwei(cn);
    	omg[0] = inv[0] = 1;
    	omg[1] = ksm(YG, MOD/Mn); inv[1] = ksm(omg[1], MOD-2);
    	for(int i = 2;i<Mn;i++) omg[i] = 1ll*omg[i-1]*omg[1]%MOD, inv[i] = 1ll*inv[i-1]*inv[1]%MOD;
    	fan[0] = 0; int lin = erwei(Mn)-2;
    	for(int i = 1;i<Mn;i++) fan[i] = (fan[i>>1]>>1) | ((i&1)<<lin);
    }
    void ntt(int a[], int omg[], int n)
    {
    	for(int i = 0;i<n;i++) a[i] = (a[i]%MOD+MOD)%MOD;
    	for(int i = 0;i<n;i++) if(fan[i] > i) swap(a[fan[i]], a[i]);
    	for(int i = 2, m = 1;i<=n;i = (m = i)<<1)
    	for(int j = 0;j<n;j+=i) 
    	for(int k = 0;k<m;k++)
    	{
    		int lin1 = a[j+k], lin2 = 1ll*a[j+k+m]*omg[Mn/i*k]%MOD;
    		a[j+k] = lin1+lin2>=MOD ? lin1+lin2-MOD : lin1+lin2;
    		a[j+k+m] = lin1>=lin2 ? lin1-lin2 : lin1-lin2+MOD;
    	}
    }
    void yuchu_qian()
    {
    	b[0] = 1;
    	for(int i = 1;i<n;i++) b[i] = 1ll*b[i-1]*(k+i-1)%MOD*ksm(i, MOD-2)%MOD;
    }
    void yuchu_cha()
    {
    	b[0] = 1; int lin = min(k+1,n-1);
    	for(int i = 1;i<=lin;i++) b[i] = -1ll*b[i-1]*(k-i+1)%MOD*ksm(i, MOD-2)%MOD;
    }
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	Read(n); Read_m(k); Read(typ);
    	for(int i = 0;i<n;i++) Read(a[i]);
    	if(typ == 0) yuchu_qian(); else yuchu_cha();
    	yuchu(n*2);
    	ntt(a, omg, Mn); ntt(b, omg, Mn);
    	for(int i = 0;i<Mn;i++) a[i] = 1ll*a[i]*b[i]%MOD;
    	ntt(a, inv, Mn); int lin = ksm(Mn, MOD-2);
    	for(int i = 0;i<Mn;i++) a[i] = 1ll*a[i]*lin%MOD;
    	for(int i = 0;i<n;i++) Write(a[i]), putchar(' '); puts(""); 
    	return 0;
    }
    
  • 相关阅读:
    C#中 File,Directory,FileInfo,DirectoryInfo区别与应用
    C#中设置开机自动运行和关机
    C# 线程手册 第三章 使用线程 小心死锁
    C# WinForm判断Win7下是否是管理员身份运行
    C#应用MemoryStream提高File读取速度
    CodeforcesDouble Profiles
    SRM533 D1 L1
    SRM532 D1 L2
    SRM533 D2 L3
    次小生成树 | 割点 | 割边
  • 原文地址:https://www.cnblogs.com/czyarl/p/13054098.html
Copyright © 2020-2023  润新知