分拆数&&HDU4651

1,有两种DP,复杂度都是O(N^2),但是浪费的侧重点不同,所以根据侧重点分块DP,复杂度可以降到O(N^1.5)。

2,母函数+五边形blabla。。。

占位。

 

 其实就是母函数拆开后,快速知道哪些X^N=哪些X^M*X^(N-M)。然后就可以递推了。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn=100010;
const int Mod=1e9+7;
ll ans[maxn+10];
ll get(int x){
    return ((ll)3*x*x-x)/2;
}
void solve()
{
    ll sig,tmp; ans[0]=1;
    for(int i=1;i<=maxn;i++){
        for(int j=1;;j++){
            tmp=get(j);
            if(tmp>i) break;
            if(j&1) ans[i]=(ans[i]+ans[i-tmp])%Mod;
            else ans[i]=(ans[i]-ans[i-tmp])%Mod;
            tmp=get(-j);
            if(tmp>i) break;
            if(j&1) ans[i]=(ans[i]+ans[i-tmp])%Mod;
            else ans[i]=(ans[i]-ans[i-tmp])%Mod;
        }
    }
}
int main()
{
    int T,N;
    solve(); scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        printf("%lld
",(ans[N]%Mod+Mod)%Mod);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hua-dong/p/8604999.html