Partition
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1079 Accepted Submission(s): 630
Now, I will give you a number n, and please tell me P(n) mod 1000000007.
4 5 11 15 19
7 56 176 490
HDU4651求的是正整数分解,可以有重复元素。(没有重复元素的考虑dp,dp[i][j]表示j个数组成i的个数,有dp[i][j]=dp[i-j][j-1]+dp[i-j][j],分别考虑j在不在里面)。
首先,欧拉函数(1-x)(1-x^2)(1-x^3)…=1 – x - x^2 + x^5 + x^7 –x^12 – x^15…. X的系数为k*(3*k+1)/2,k*(3*k+1)/2留下来的次方正好是五边形数
然后欧拉函数的倒数是分割函数的母函数,假设p(k)为k的分割数,推过来就有
(1-x- x^2 +x^5 +x^7 –x^12 –x^15 + x^22 + x^26+ …)(1+ p(1)*x + p(2)*x^2 + p(3)*x^3 +…) = 1
比较等式两边的系数,可得到p(n)-p(n-1)-p(n-2)+p(n-5)+p(n-7)+…=0
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define INF 0x333f3f3f
#define repp(i, n, m) for (int i = n; i <= m; i++)
#define rep(i, n, m) for (int i = n; i < m; i++)
#define sa(n) scanf("%d", &(n))
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const double PI = acos(-1.0);
int n;
int k[maxn];
ll res[maxn];
void init()
{
int i, j;
int num = 0;
for (i = 1; i <= 1000; i++)
{
for (j = 1; j <= 2; j++)
{
if (j & 1)
{
k[num] = i*(3 * i - 1) / 2;
num++;
}
else
{
k[num] = i*(3 * i + 1) / 2;
num++;
}
}
}
res[0] = 1;
for (i = 1; i <= 100000; i++)
{
for (j = 0; j < num; j++)
{
if (i - k[j] >= 0)
{
if (j % 4 < 2)
{
res[i] += (res[i - k[j]]) % mod;
res[i] %= mod;
}
else
{
res[i] -= (res[i - k[j]]) % mod;
res[i] = (res[i] % mod + mod) % mod;
}
}
else
{
break;
}
}
}
}
void solve()
{
int n;
sa(n);
printf("%lld\n", res[n]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("i.txt", "r", stdin);
freopen("o.txt", "w", stdout);
#endif
init();
int t;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}
Integer Partition
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 574 Accepted Submission(s): 267
Following are T lines. Each line contains two numbers, n and k.
1<=n,k,T<=10 5
Since the numbers can be very large, you should output them modulo 10 9+7.
4 4 2 4 3 4 4 4 5
2 4 4 5
HDU4658参考了http://blog.youkuaiyun.com/whai362/article/details/42530243这篇博客,这个题的母函数
G(x)=( 1 + x + x^2 +...+ x^(k-1) ) * ( 1 + x^2 +x^4 +...+ x^((k-1)*2) ) *...
=(1-x^k)/(1-x) * (1-x^(k*2))/(1-x^2)* ...
=( (1-x^k) * (1-(x^k)^2) *... ) / ((1-x) * (1-x^2) *... )
=Q(x^k)/Q(x) (Q(x)为欧拉函数,根据上述定理可得)
=Q(x^k)*P(x)
=( 1 - x^k - (x^k)^2 + (x^k)^5 +(x^k)^7 -... ) * ( 1 + x + 2*x^2 + 3*x^3 + 5*x^4 + 7*x^5 + ... )
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define INF 0x333f3f3f
#define repp(i, n, m) for (int i = n; i <= m; i++)
#define rep(i, n, m) for (int i = n; i < m; i++)
#define sa(n) scanf("%d", &(n))
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const double PI = acos(-1.0);
int n;
int k[maxn];
int res[maxn];
void init()
{
int i, j;
int num = 0;
for (i = 1; i <= 1000; i++)
{
for (j = 1; j <= 2; j++)
{
if (j & 1)
{
num++;
k[num] = i*(3 * i - 1) / 2;
}
else
{
num++;
k[num] = i*(3 * i + 1) / 2;
}
}
}
res[0] = 1;
for (i = 1; i <= 100000; i++)
{
for (j = 1; j <= num; j++)
{
if (i - k[j] >= 0)
{
if ((j-1) % 4 < 2)
{
res[i] += (res[i - k[j]]);
if (res[i] >= mod)
res[i] -= mod;
}
else
{
res[i] -= (res[i - k[j]]);
if (res[i] < 0)
res[i] += mod;
}
}
else
{
break;
}
}
}
}
void solve()
{
int n, kk;
int i, j;
int ans;
sa(n), sa(kk);
ans = res[n];
for (i = 1;; i++)
{
int t = kk*k[i];
if (t > n)
break;
if ((i - 1) % 4 < 2)
{
ans = (ans - res[n - t] + mod) % mod;
}
else
{
ans = (ans + res[n - t]) % mod;
}
}
printf("%d\n", ans);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("i.txt", "r", stdin);
freopen("o.txt", "w", stdout);
#endif
init();
int t;
scanf("%d", &t);
while (t--)
{
solve();
}
//system("pause");
return 0;
}