HDU-5730(CDQ+FFT/NTT)

HDU-5730(CDQ+FFT/NTT)

题意:将长度为\(n\)的序列分成若干段,每段\([l,r]\)的权值为\(a_{r-l+1}\),一种分法的权值为所有段的乘积,求所有可能的分法的权值和

根据题意可以得到简单\(dp\)

\(dp_0=1,dp_i=\sum_0^{i-1}dp_j \cdot a_{i-j}\)

可以看到是一个\(i-j\)形式的作差卷积

但是直接卷积我们无法保证先求出了\(dp_j\),所有可以用\(CDQ\)分治优化,复杂度\(n\log^2 n\)

具体实现见代码

#include
using namespace std;

#define reg register
typedef long long ll;
#define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)

template  inline void cmin(T &a,T b){ ((a>b)&&(a=b)); } 
template  inline void cmax(T &a,T b){ ((ai) swap(a[i],a[rev[i]]);
    for(reg int i=1;i>1;
    Solve(l,mid); //先求出左边所有的
    
    int R=1,c=-1;
    while(R<=r-l+1) R<<=1,c++;
    rep(i,1,R) rev[i]=(rev[i>>1]>>1)|((i&1)<

你可能感兴趣的:(HDU-5730(CDQ+FFT/NTT))