您的位置:首页 > 其它

HDU 4651&&HDU 4658 五边形数定理

2016-04-26 22:02 375 查看


Partition

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1079    Accepted Submission(s): 630


Problem Description

How many ways can the numbers 1 to 15 be added together to make 15? The technical term for what you are asking is the "number of partition" which is often called P(n). A partition of n is a collection of positive integers (not necessarily distinct) whose sum
equals n.

Now, I will give you a number n, and please tell me P(n) mod 1000000007.

 

Input

The first line contains a number T(1 ≤ T ≤ 100), which is the number of the case number. The next T lines, each line contains a number n(1 ≤ n ≤ 105) you need to consider.

 

Output

For each n, output P(n) in a single line.

 

Sample Input

4
5
11
15
19

 

Sample Output

7
56
176
490

 

Source

2013 Multi-University Training Contest 5

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

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


Problem Description

Given n, k, calculate the number of different (unordered) partitions of n such that no part is repeated k or more times. 

 

Input

First line, number of test cases, T. 

Following are T lines. Each line contains two numbers, n and k. 

1<=n,k,T<=105

 

Output

T lines, each line contains answer to the responding test case. 

Since the numbers can be very large, you should output them modulo 109+7.

 

Sample Input

4
4 2
4 3
4 4
4 5

 

Sample Output

2
4
4
5

 

Source

2013 Multi-University Training Contest 6

HDU4658参考了http://blog.csdn.net/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
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: