CF632E Thief in a Shop

从$n$物品个里面取$k$个,有多少种价值组合。

即$(x^{a_1}+x^{a_2}+x^{a_i})^k$

卷个积(此处可以用先$DFT$,然后$f^k(x)$,然后$IDFT$)(也可以用多项式快速幂吧)

卡了个模数,用两个模数即可。


代码

```c++

include

using namespace std;
typedef long long ll;

define pii pair

define mk make_pair

const int N = 4e6 + 10;

//const int P = 1e9 + 7;
int P = 998244353, gi = 3;
const double pi = acos(-1.0);
int inc(int x, int y, int mo)
{
if (x + y >= mo)
return (x + y - mo);
else
return (x + y);
}

int del(int x, int y, int mo)
{
if (x - y < 0)
return (x - y + mo);
else
return (x - y);
}
int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < ‘0’ || c > ‘9’)
{
if (c == ‘-‘)
f = -1;
c = getchar();
}
while (c >= ‘0’ && c <= ‘9’)
x = (x << 1) + (x << 3) + c - ‘0’, c = getchar();
return x * f;
}

int qpow(int a, int x, int mo)
{
int res = 1;
while (x)
{
if (x & 1)
res = 1ll res a % mo;
x >>= 1;
a = 1ll a a % mo;
}
return res;
}
int rev[N];
void NTT(int A, int n, int inv)
{
for (int i = 0; i < n; i++)
if (i < rev[i])
swap(A[i], A[rev[i]]);
for (int l = 1; l < n; l <<= 1)
{
int tt = qpow(gi, (P - 1) / (l << 1), P);
int temp = (inv == 1 ? tt : qpow(tt, P - 2, P));
for (int i = 0; i < n; i += (l << 1))
{
int omega = 1;
for (int j = 0; j < l; j++, omega = 1ll
omega temp % P)
{
int x = A[i + j], y = 1ll
omega A[i + j + l] % P;
A[i + j] = inc(x, y, P);
A[i + j + l] = del(x, y, P);
}
}
}
int invv = qpow(n, P - 2, P);
if (inv == -1)
for (int i = 0; i < n; i++)
A[i] = 1ll
A[i] * invv % P;
}

void QPOWNTTX(int a, int n, int b, int m, int ans)
{
int ML = 1, bit = 0;
while (ML < n + m)
ML <<= 1, bit++;
for (int i = 0; i < ML; i++)
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
NTT(a, ML, 1);
NTT(b, ML, 1);
for (int i = 0; i < ML; i++)
a[i] = 1ll
a[i] b[i] % P;
NTT(a, ML, -1);
}
int f[N], g[N];
int main()
{
int n = read(), k = read();
for (int i = 1; i <= n; i++)
{
int x = read();
f[x] = 1;
g[x] = 1;
}
n = 1000
k;
int ML = 1, bit = 0;
while (ML <= n + n)
ML <<= 1, bit++;
for (int i = 0; i < ML; i++)
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
NTT(f, ML, 1);
for (int i = 0; i < ML; i++)
f[i] = qpow(f[i], k, P) % P;
NTT(f, ML, -1);
P = 1004535809;
NTT(g, ML, 1);
for (int i = 0; i < ML; i++)
g[i] = qpow(g[i], k, P) % P;
NTT(g, ML, -1);
for (int i = 1; i <= n; i++)
if (g[i] | f[i])
printf(“%d “, i);
}