zoukankan      html  css  js  c++  java
  • 分治NTT:我 卷 我 自 己

    感觉这种东西每次重推一遍怪麻烦的,就写在这里了。

    说白了就是根据分治区间左端点是否为(0)分类讨论一下,一般是如果不是(0)就要乘(2),不过还是需要具体问题具体分析一下才好(就比如下面的例子)。

    以下面这个东西为例给出代码:

    [f[0]=0,g[0]=0,f[1]=0,g[1]=1 ]

    [f[n]=sum_{i=0}^{n}inom{n-2}{i-1}(f[i]f[n-i]+g[i]f[n-i]+g[i]g[n-i]) ]

    [g[n]=sum_{i=0}^{n}inom{n-2}{i-1}f[i]g[n-i] ]

    void solve(int l,int r){
    	if(l==r){
    		if(l==0)f[l]=g[l]=0;
    		else if(l==1)f[l]=0,g[l]=1;
    		else f[l]=1ll*f[l]*fac[l-2]%MOD,g[l]=1ll*g[l]*fac[l-2]%MOD;
    		return;
    	}
    	int mid=((l+r)>>1);solve(l,mid);
    	m=(mid-l)+(r-l);prepare();
    	rin(i,0,mid-l)A[i]=1ll*f[l+i]*(l+i==0?0:invf[l+i-1])%MOD,B[i]=1ll*g[l+i]*(l+i==0?0:invf[l+i-1])%MOD;
    	rin(i,0,r-l)C[i]=1ll*f[i]*(i==0?0:invf[i-1])%MOD,D[i]=1ll*g[i]*(i==0?0:invf[i-1])%MOD;
    	ntt(A,1);ntt(B,1);ntt(C,1);ntt(D,1);
    	rin(i,0,n-1){
    		int temp=A[i];
    		A[i]=((l==0?1ll:2ll)*A[i]*C[i]+1ll*B[i]*C[i]+(l==0?0ll:1ll)*A[i]*D[i]+(l==0?1ll:2ll)*B[i]*D[i])%MOD;
    		B[i]=(1ll*B[i]*C[i]+(l==0?0ll:1ll)*temp*D[i])%MOD;
    	}
    	ntt(A,-1);ntt(B,-1);
    	rin(i,mid+1,r)f[i]=(f[i]+A[i-l])%MOD,g[i]=(g[i]+B[i-l])%MOD;
    	memset(A,0,n<<2);memset(B,0,n<<2);memset(C,0,n<<2);memset(D,0,n<<2);
    	solve(mid+1,r);
    }
    
  • 相关阅读:
    【HDOJ】2267 How Many People Can Survive
    【HDOJ】2268 How To Use The Car
    【HDOJ】2266 How Many Equations Can You Find
    【POJ】2278 DNA Sequence
    【ZOJ】3430 Detect the Virus
    【HDOJ】2896 病毒侵袭
    求奇数的乘积
    平方和与立方和
    求数列的和
    水仙花数
  • 原文地址:https://www.cnblogs.com/ErkkiErkko/p/10604160.html
Copyright © 2011-2022 走看看