题目大意:给定一个长度为 \(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. 最新 4399java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.4399等10家互联网公司的校招Offer,因为某些自身原因最终选择了4399.6.7月主要是做系统复习.项目复盘.Leet ...

  2. poj2826(细节,计算几何)

    题目链接:https://vjudge.net/problem/POJ-2826 题意:平面中摆两根木棍,雨水从上垂直下落,问木棍中能乘多少水. 思路: 细节很多,坑QAQ.. 首先不相交时肯定为0. ...

  3. 如何克服社交恐惧症?zz

    zhang Bavol 清华大学核能与新能源技术研究院——核科学与技术/电子爱好者     你说的这个恐惧症我也有一点点,不过现在我是只对那种不是很熟悉的七姑八婆之类的亲戚才会有这种憋屈感觉,对朋友和 ...

  4. [转帖]yaml语言格式

    yaml语言格式 YAML是"YAML Ain't a Markup Language"(YAML不是一种标记语言),强调这种语言以数据做为中心,而不是以置标语言为重点. 转载2篇 ...

  5. Kubernetes---资源控制器之ReplicationController、ReplicaSet和Deployment

    1.ReplicationController和ReplicaSet介绍 RC(ReplicationController)主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数.即如果有容 ...

  6. split(".")不生效的问题

    前言:今天用String的split(".")函数分割字符串,结果总是一个空的String数组: 解决:输入的regex是一个正则表达式,很多在正则表达式里面有特殊意义的比如 &q ...

  7. ARM-常见考题和知识点

    1. ARMv7 7中状态,ARMv8对应的状态 2. TEE知识 3. ARM寄存器及作用 4. ARM内部总线AHB APB 5. 1. Thumb | Arm指令区别 编写Thumb指令时,先要 ...

  8. windows下安装mongoDB(zip版)

    windows下安装mongoDB(zip版) 下面说明如何在win10下用zip包安装好mongoDB数据库 首先要先从网上下载mongoDB的zip包 http://dl.mongodb.org/ ...

  9. C#签名验签帮助类

    using System; using System.IO; using System.Text; using System.Collections.Generic; using System.Sec ...

  10. TCP协议探究(三):RTT、滑动窗口和阻塞处理

    1 RTT算法 1.1 概述 上一节说了重传机制需要设置一个重传超时值(RTO,Retransmission TimeOut),RTO设长了,重发太慢:设短了,可能导致包没有丢,就重发了,可能导致雪崩 ...