消失之物 多项式题解

我们构造一个生成函数

f ( x , y ) = ∏ i = 1 n ∧ [ i ≠ y ] ( 1 + x v i ) c n t ( a , b ) = [ x b ] f ( x , a ) \begin{aligned} f (x, y) = \prod_{i = 1}^{n \wedge [i \neq y]} (1+x^{v_i}) \\ cnt (a,b) = [x^{b}]f (x,a) \end{aligned} f(x,y)=i=1n[i=y](1+xvi)cnt(a,b)=[xb]f(x,a)

我们可以把 f f f 换个形式

令 f ( x ) = ∏ i = 1 n ( 1 + x v i ) f ( x , y ) = f ( x ) 1 + x v y 1 1 + x v y = ∑ i = 0 + ∞ ( − 1 ) i x i ⋅ v y f ( x , y ) = f ( x ) ∑ i = 0 + ∞ ( − 1 ) i x i ⋅ v y c n t ( a , b ) = [ x b ] f ( x , a ) = [ x b ] f ( x ) ∑ i = 0 + ∞ ( − 1 ) i x i ⋅ v y = [ x b ] ∑ i = 0 + ∞ f ( x ) ( − 1 ) i x i ⋅ v y = ∑ i = 0 b − i ⋅ v y ≥ 0 ( [ x b − i ⋅ v y ] f ( x ) ) ( − 1 ) i \begin{aligned} 令 f (x) &= \prod_{i = 1}^{n} (1+x^{v_i}) \\ f(x,y) &= \frac{f (x)}{1+x^{v_y}} \\ \frac{1}{1+x^{v_y}} &= \sum_{i = 0}^{+\infty} (-1)^{i} x^{i \cdot v_y} \\ f(x,y) &= f(x) \sum_{i = 0}^{+\infty} (-1)^{i}x^{i \cdot v_y} \\ cnt (a, b) &= [x^{b}] f(x,a) \\ &= [x^{b}] f (x) \sum_{i = 0}^{+\infty} (-1)^{i}x^{i \cdot v_y} \\ &= [x^{b}] \sum_{i = 0}^{+\infty} f(x) (-1)^{i}x^{i \cdot v_y} \\ &= \sum_{i = 0}^{b-i \cdot v_y \geq 0} ([x^{b - i \cdot v_y}]f(x)) (-1)^{i} \end{aligned} f(x)f(x,y)1+xvy1f(x,y)cnt(a,b)=i=1n(1+xvi)=1+xvyf(x)=i=0+(1)ixivy=f(x)i=0+(1)ixivy=[xb]f(x,a)=[xb]f(x)i=0+(1)ixivy=[xb]i=0+f(x)(1)ixivy=i=0bivy0([xbivy]f(x))(1)i

下标等差求和,用个前缀和数组保存下就行了。

#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 = 2000;

int n, m;
int a[Maxn + 5];
int f[Maxn + 5], pre[Maxn + 5];

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

    read (n, m);
    rep (i, 1, n) read (a[i]);

    f[0] = 1;
    rep (i, 1, n) {
        per (j, m, a[i])
            f[j] = (f[j] + f[j - a[i]]) % 10;
    }
    rep (i, 1, n) {
        rep (j, 0, m) pre[j] = f[j];
        rep (j, a[i], m)
            pre[j] = ((f[j] - pre[j - a[i]]) + 10) % 10;
        rep (j, 1, m)
            write (pre[j]);
        putchar ('\n');
    }
	return 0;
}
posted @ 2022-10-07 11:16  C2022lihan  阅读(16)  评论(0编辑  收藏  举报