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; }