题目大意:给定一个长度为 \(N\) 的序列,求从序列中选出 \(K\) 个数的集合乘积之和是多少。

题解:

由于是选出 \(K\) 个数字组成的集合,可知对于要计算的 \(K\) 元组来说是没有标号的,而元组是由序列中 \(N\) 个数字组合而成的。因此,将要求的元组看作组合对象,该组合对象是由 \(N\) 个不同种类的组合对象组成的,且组合对象是没有标号的,因此采用普通生成函数计算即可。

对于第 \(i\) 个数的普通生成函数为 $$(1 + a_ix)$$,因此,原组合对象的生成函数是$$\prod\limits_{i = 1}^{n}(1+a_ix)$$。可以通过分治乘法来进行计算,时间复杂度为 \(O(nlogn)\)。

代码如下

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int mod = 998244353, g = 3, ig = 332748118;

LL fpow(LL a, LL b, LL c) {
LL ret = 1 % c;
for (; b; b >>= 1, a = a * a % mod) if (b & 1) ret = ret * a % mod;
return ret;
} void ntt(vector<LL> &v, vector<int> &rev, int opt) {
int tot = v.size();
for (int i = 0; i < tot; i++) if (i < rev[i]) swap(v[i], v[rev[i]]);
for (int mid = 1; mid < tot; mid <<= 1) {
LL wn = fpow(opt == 1 ? g : ig, (mod - 1) / (mid << 1), mod);
for (int j = 0; j < tot; j += mid << 1) {
LL w = 1;
for (int k = 0; k < mid; k++) {
LL x = v[j + k], y = v[j + mid + k] * w % mod;
v[j + k] = (x + y) % mod, v[j + mid + k] = (x - y + mod) % mod;
w = w * wn % mod;
}
}
}
if (opt == -1) {
LL itot = fpow(tot, mod - 2, mod);
for (int i = 0; i < tot; i++) v[i] = v[i] * itot % mod;
}
} vector<LL> convolution(vector<LL> &a, int cnta, vector<LL> &b, int cntb, const function<LL(LL, LL)> &calc) {
int bit = 0, tot = 1;
while (tot <= 2 * max(cnta, cntb)) bit++, tot <<= 1;
vector<int> rev(tot);
for (int i = 0; i < tot; i++) rev[i] = rev[i >> 1] >> 1 | (i & 1) << (bit - 1);
vector<LL> foo(tot), bar(tot);
for (int i = 0; i < cnta; i++) foo[i] = a[i];
for (int i = 0; i < cntb; i++) bar[i] = b[i];
ntt(foo, rev, 1), ntt(bar, rev, 1);
for (int i = 0; i < tot; i++) foo[i] = calc(foo[i], bar[i]);
ntt(foo, rev, -1);
return foo;
} int main() {
//freopen("data.in", "r", stdin);
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, K;
cin >> n >> K;
vector<LL> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int m;
cin >> m;
while (m--) {
int opt;
cin >> opt;
vector<LL> b = a;
if (opt == 1) {
int q, x, y;
cin >> q >> x >> y;
x--;
b[x] = y;
for (int i = 0; i < n; i++) {
b[i] = (q - b[i] + mod) % mod;
}
} else {
int q, l, r, d;
cin >> q >> l >> r >> d;
l--, r--;
for (int i = l; i <= r; i++) {
b[i] = (b[i] + d) % mod;
}
for (int i = 0; i < n; i++) {
b[i] = (q - b[i] + mod) % mod;
}
}
function<vector<LL>(int, int)> solve = [&](int l, int r) {
if (l == r) {
return vector<LL> {1, b[l]};
}
int mid = l + r >> 1;
vector<LL> ls = solve(l, mid);
vector<LL> rs = solve(mid + 1, r);
return convolution(ls, mid - l + 2, rs, r - mid + 1, [&](LL a, LL b) {
return a * b % mod;
});
};
vector<LL> ans = solve(0, n - 1);
cout << ans[K] << endl;
}
return 0;
}

【CF1218E】Product Tuples的更多相关文章

  1. 【leetcode81】Product of Array Except Self

    题目描述: 给定一个长度为n的整数数组Array[],输出一个等长的数组result[],这个输出数组,对应位置i是除了Array[i]之外,其他的所有元素的乘积 例如: given [1,2,3,4 ...

  2. 【LeetCode】Product of Array Except Self

    Product of Array Except Self Given an array of n integers where n > 1, nums, return an array outp ...

  3. 【08_238】Product of Array Except Self

    Product of Array Except Self Total Accepted: 26470 Total Submissions: 66930 Difficulty: Medium Given ...

  4. 【数组】Product of Array Except Self

    题目: iven an array of n integers where n > 1, nums, return an array output such that output[i] is ...

  5. 【xsy2978】Product of Roots 生成函数+多项式ln+多项式exp

    题目大意:给你两个多项式$f(x)$和$g(x)$,满足$f(x)=\prod\limits_{i=1}^{n}(a_i+1)$,$g(x)=\prod\limits_{i=1}^{m}(b_i+1) ...

  6. 【题解】Product

    \(\color{brown}{Link}\) \(\text{Solution:}\) \(Question:\) \(\prod_{i=1}^n \prod_{j=1}^n \frac{lcm(i ...

  7. 敏捷开发中的Scrum流程和术语【转】

    任何人力流程都离不开人来执行,所以在讲解Scrum流程之前,有必要先把Scrum中的角色讲一下. 一天,一头猪和一只鸡在路上散步,鸡看了一下猪说,“嗨,我们合伙开一家餐馆怎么样?”,猪回头看了一下鸡说 ...

  8. 【CF660E】Different Subsets For All Tuples 结论题

    [CF660E]Different Subsets For All Tuples 题意:对于所有长度为n,每个数为1,2...m的序列,求出每个序列的本质不同的子序列的数目之和.(多个原序列可以有相同 ...

  9. 【Python】itertools之product函数

    [转载]源博客 product 用于求多个可迭代对象的笛卡尔积(Cartesian Product),它跟嵌套的 for 循环等价.即: product(A, B) 和 ((x,y) for x in ...

随机推荐

  1. Odoo 13 released..

    origin https://medium.com/@jc_57445/odoo-13-is-fantastic-f2b421696b49 Most striking changes The most ...

  2. leveldb单元测试之宏定义源码剖析

    前言 leveldb 是一个库,没有 main() 函数入口, 故非常难理清其中的代码逻辑.但好在库中有非常多的单元测试代码,帮助读者理解其中的各个模块的功能.然而,测试代码个人觉得一开始看时非常费解 ...

  3. 主成分分析(PCA)与线性判别分析(LDA)

    主成分分析 线性.非监督.全局的降维算法 PCA最大方差理论 出发点:在信号处理领域,信号具有较大方差,噪声具有较小方差 目标:最大化投影方差,让数据在主投影方向上方差最大 PCA的求解方法: 对样本 ...

  4. 把Javascript 对象转换为键值对连接符字符串的方法总结

    307down votefavorite 93 Do you know a fast and simple way to encode a Javascript Object into a strin ...

  5. Equations HDU - 1496(哈希的应用)

    Problem Description Consider equations having the following form: a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 a, b ...

  6. lxml and 代理ip

    pip install lxml 导包From lxml import etree 1. 注意这个是本地html就直接使用etree.parse即可 2. html_etree=etree.parse ...

  7. hdu 6069 Counting divisors 公式+区间筛

    比赛的时候把公式扣出来了,,但是没有想到用筛法算公因子,,默默学习一下.. 题解:设n=p1^(c1)p2^{c2}...pm^{cm},n=p​1^​c​1*​​​​p​2​^c​2​​​​...p ...

  8. SP338ROADS题解--最短路变式

    题目链接 https://www.luogu.org/problemnew/show/SP338 分析 联想到不久前做过的一道题\(Full\) \(Tank\),感觉可以用优先队列做,于是写了\(d ...

  9. NodeJS express框架的使用

    首先,可以通过npm或者淘宝镜像cnpm全局安装epress框架,这里不具体说了 npm install -g expressnpm install -g express-generator 新建一个 ...

  10. react快速上手二(使用JSX语法)

    前提: 下载依赖,配置 cnpm i babel-preset-react -D JSX语法的本质: 还是以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代 ...