Partition 多项式题解

f ( n ) = ∏ i = 1 n ∑ j = 0 + ∞ x i ⋅ j ( 1 ) a n s = [ x n ] f ( n ) f ( n ) = ∏ i = 1 n x + ∞ − 1 x i − 1 \begin{aligned} f (n) &= \prod_{i=1}^{n} \sum_{j = 0}^{+ \infty} x^{i \cdot j} \big( 1 \big) \\ ans &= [x^{n}]f (n) \\ f (n) &= \prod_{i=1}^{n} \frac{x ^ {+\infty} - 1}{x ^ i - 1} \end{aligned} f(n)ansf(n)=i=1nj=0+xij(1)=[xn]f(n)=i=1nxi1x+1

不妨令 x ∈ ( − 1 , 1 ) x \in (-1, 1) x(1,1),使函数 ( y = x + ∞ − 1 y = x^{+\infty} - 1 y=x+1) 具有收敛性

f ( n ) = ∏ i = 1 n 1 1 − x i ( 2 ) \begin{aligned} f (n) &= \prod_{i = 1}^{n} \frac{1}{1 - x ^ i} (2) \end{aligned} f(n)=i=1n1xi1(2)

Ps: ( 1 ) (1) (1) ( 2 ) (2) (2) 也可用多项式求逆理解

法 1:

在这里插入图片描述
利用杨表,枚举红色正方形的大小(这个红色正方形是极大满正方形),边长记作 h h h,然后 f ( n ) f (n) f(n) 就可以递归求解了。

f ( n ) f(n) f(n) 就是将红色正方形填充满,然后剩余部分随便填,理应是一个 ( n − h ) ∗ h (n - h) * h (nh)h 的矩形,但是由于 h 2 ≤ n h ^ 2 \leq n h2n,所以 n − h ≥ h n - h \geq h nhh,就可以看成是 h × h h \times h h×h 的正方形,多项式及为 f ( h ) f (h) f(h)

f ( n ) = ∏ i = 1 n 1 1 − x i = ∑ h = 1 h 2 ≤ n x h 2 f 2 ( h ) \begin{aligned} f (n) &= \prod_{i = 1}^{n} \frac{1}{1 - x ^ i} \\ &= \sum_{h = 1} ^ {h^2 \leq n} x^{h^2} f ^ 2 (h) \\ \end{aligned} f(n)=i=1n1xi1=h=1h2nxh2f2(h)

#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define fi first
#define se second
#define db double
#define LL long long
// #define int long long
#define PII pair <int, int>
#define ULL unsigned long long
#define MP(x,y) make_pair (x, y)
#define rep(i,j,k) for (int i = (j); i <= (k); i++)
#define per(i,j,k) for (int i = (j); i >= (k); i--)

template <typename T>
void read (T &x) {
	x = 0; T f = 1; 
	char ch = getchar ();
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -1;
		ch = getchar ();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar ();
	}
	x *= f;
}
template <typename T, typename... Args>
void read (T &x, Args&... Arg) {
	read (x), read (Arg...);
}
const int MaxPrint = 1000;
int Poi_For_Print, Tmp_For_Print[MaxPrint + 5];
template <typename T>
void write (T x) {
	if (x == 0) {
		putchar ('0');
		return;
	}
	bool flag = (x < 0 ? 1 : 0);
	x = (x < 0 ? -x : x);
	while (x) Tmp_For_Print[++Poi_For_Print] = x % 10, x /= 10;
	if (flag) putchar ('-');
	while (Poi_For_Print) putchar (Tmp_For_Print[Poi_For_Print--] + '0');
}
template <typename T, typename... Args>
void write (T x, Args... Arg) {
	write (x); putchar (' '); write (Arg...);
}
template <typename T, typename... Args>
void print (T x, char ch) {
	write (x); putchar (ch);
}
template <typename T> T Max (T x, T y) { return x > y ? x : y; }
template <typename T> T Min (T x, T y) { return x < y ? x : y; }
template <typename T> T Abs (T x) { return x > 0 ? x : -x; }

const int Maxn = 1e5;
const int Maxsn = 500;
const LL Mod = 1000000007;

int t, n;
LL dp[Maxn + 5];
//dp[i][j] 保存 [j]f (i),统计答案时自己卷自己一次

signed main () {
//	freopen ("D:\\lihan\\1.in", "r", stdin);
//	freopen ("D:\\lihan\\1.out", "w", stdout);

/*
    rep (i, 0, Maxn)
        dp[1][i] = 1;
    rep (i, 2, Maxsn) {
        rep (j, 0, i - 1) dp[i][j] = dp[i - 1][j];
        rep (j, i, Maxn)
            dp[i][j] = (dp[i - 1][j] + dp[i][j - i]) % Mod;
    }
    read (t);
    while (t--) {
        read (n);
        LL res = 0;
        for (int h = 1; h <= n / h; h++) {
//            res = (res + dp[h][h * h] * dp[h][n - h * h]) % Mod;
			rep (i, 0, n - h * h)
				res = (res + dp[h][i] % Mod * dp[h][n - h * h - i]) % Mod;
        }
        print (res, '\n');
    }
*/

    read (t);
    while (t--) {
        read (n);
        
        int b = sqrt (n);
        LL res = 0;
	    rep (i, 0, n)
	        dp[i] = 1;
	    rep (i, 0, n - 1 * 1)
	    	res = (res + dp[i] * dp[n - 1 * 1 - 1]) % Mod;
	    rep (i, 2, b) {
			rep (j, i, n)
				dp[j] = (dp[j] + dp[j - i]) % Mod;
			rep (j, 0, n - i * i)
				res = (res + dp[j] * dp[n - i * i - j]) % Mod;
	    }
        print (res, '\n');
    }
	return 0;
}
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define fi first
#define se second
#define db double
#define LL long long
// #define int long long
#define PII pair <int, int>
#define ULL unsigned long long
#define MP(x,y) make_pair (x, y)
#define rep(i,j,k) for (int i = (j); i <= (k); i++)
#define per(i,j,k) for (int i = (j); i >= (k); i--)

template <typename T>
void read (T &x) {
	x = 0; T f = 1; 
	char ch = getchar ();
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -1;
		ch = getchar ();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar ();
	}
	x *= f;
}
template <typename T, typename... Args>
void read (T &x, Args&... Arg) {
	read (x), read (Arg...);
}
const int MaxPrint = 1000;
int Poi_For_Print, Tmp_For_Print[MaxPrint + 5];
template <typename T>
void write (T x) {
	if (x == 0) {
		putchar ('0');
		return;
	}
	bool flag = (x < 0 ? 1 : 0);
	x = (x < 0 ? -x : x);
	while (x) Tmp_For_Print[++Poi_For_Print] = x % 10, x /= 10;
	if (flag) putchar ('-');
	while (Poi_For_Print) putchar (Tmp_For_Print[Poi_For_Print--] + '0');
}
template <typename T, typename... Args>
void write (T x, Args... Arg) {
	write (x); putchar (' '); write (Arg...);
}
template <typename T, typename... Args>
void print (T x, char ch) {
	write (x); putchar (ch);
}
template <typename T> T Max (T x, T y) { return x > y ? x : y; }
template <typename T> T Min (T x, T y) { return x < y ? x : y; }
template <typename T> T Abs (T x) { return x > 0 ? x : -x; }

const int Maxn = 1e5;
const int Maxsn = 500;
const LL Mod = 1000000007;

int t, n;
LL dp[Maxn + 5], ans[Maxn + 5];
//dp[i][j] 保存 [j](f (i)^2),统计答案时直接卷上 (i^{2})

signed main () {
//	freopen ("D:\\lihan\\1.in", "r", stdin);
//	freopen ("D:\\lihan\\1.out", "w", stdout);
	
	n = Maxn;
	int b = sqrt (n);
	dp[0] = 1;
	rep (i, 1, b) {
		rep (step, 1, 2)
			rep (j, i, n) 
				dp[j] = (dp[j] + dp[j - i]) % Mod;
		rep (j, i * i, n)
			ans[j] = (ans[j] + dp[j - i * i]) % Mod;
	}
	read (t);
	while (t--) {
		read (n);
		print (ans[n], '\n');
	}
	return 0;
}
posted @ 2022-10-07 11:59  C2022lihan  阅读(12)  评论(0编辑  收藏  举报