题目大意:给定一个长度为 \(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. leveldb单元测试之宏定义源码剖析

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

  2. NLP文本清理时常用的python小函数

    # coding = utf-8 import re 1. 清理杂七杂八字符 ''' [a-zA-Z0-9] 字母数字 [\u4e00-\u9fa5] 汉字的utf-8 code范围 ''' # 保留 ...

  3. powerDesigner的建表语句默认设置为去掉双引号

    powerDesigner的建表语句默认设置为去掉双引号,依次执行如下操作: Database ------>> Edit Current DBMS ------>> Scri ...

  4. jupyter的控件交互

    jupyter实现控件交互 jupyter notebook 是一个交互式IDE 直接上jupyter notebook界面截图

  5. 20190716-Python网络数据采集/第 2 章 复杂HTML解析

    # P29/9# 解析,要考虑到可持续性问题,对方反爬修改后,仍继续有效,方为优秀代码# 解析一个目标网页前,需要做到以下几点:(1)明确目标内容:(2)寻找“打印此页”的链接,或查看网站有无HTML ...

  6. Python3 中,一行可以书写多个语句,一个语句可以分成多行书写

    Python3 中,一行可以书写多个语句 语句之间用分号隔开即可 print('I love you');print('very much!') Python3 中,一个语句可以分成多行书写 一行过长 ...

  7. CDN内容分发

    什么是CDN内容分发: CDN的全称是Content Delivery Network,即内容分发网络.CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡.内容分 ...

  8. javascript——HTML对象

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. 3、详解 ESLint 规则 转自https://blog.csdn.net/bbsyi/article/details/88816637

    什么是 ESLint ? ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误.在许多方面,它和 JSLint.JSHi ...

  10. QT开发小技巧-窗口处理(一)

    this->setWindowFlags(Qt::WindowCloseButtonHint); // 仅保留关闭按钮 this->setAttribute(Qt::WA_DeleteOn ...