【CF1218E】Product Tuples
题目大意:给定一个长度为 \(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的更多相关文章
- 【leetcode81】Product of Array Except Self
题目描述: 给定一个长度为n的整数数组Array[],输出一个等长的数组result[],这个输出数组,对应位置i是除了Array[i]之外,其他的所有元素的乘积 例如: given [1,2,3,4 ...
- 【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 ...
- 【08_238】Product of Array Except Self
Product of Array Except Self Total Accepted: 26470 Total Submissions: 66930 Difficulty: Medium Given ...
- 【数组】Product of Array Except Self
题目: iven an array of n integers where n > 1, nums, return an array output such that output[i] is ...
- 【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) ...
- 【题解】Product
\(\color{brown}{Link}\) \(\text{Solution:}\) \(Question:\) \(\prod_{i=1}^n \prod_{j=1}^n \frac{lcm(i ...
- 敏捷开发中的Scrum流程和术语【转】
任何人力流程都离不开人来执行,所以在讲解Scrum流程之前,有必要先把Scrum中的角色讲一下. 一天,一头猪和一只鸡在路上散步,鸡看了一下猪说,“嗨,我们合伙开一家餐馆怎么样?”,猪回头看了一下鸡说 ...
- 【CF660E】Different Subsets For All Tuples 结论题
[CF660E]Different Subsets For All Tuples 题意:对于所有长度为n,每个数为1,2...m的序列,求出每个序列的本质不同的子序列的数目之和.(多个原序列可以有相同 ...
- 【Python】itertools之product函数
[转载]源博客 product 用于求多个可迭代对象的笛卡尔积(Cartesian Product),它跟嵌套的 for 循环等价.即: product(A, B) 和 ((x,y) for x in ...
随机推荐
- Charles系列三:Charles打断点(包含修改请求,修改返回的内容),模拟慢速网络(弱网测试),域名映射,过滤请求,接口调试,打压测试
一:Charles断点的使用(包含修改请求,修改返回的数据) 设置断点来修改请求和返回的数据,在开发过程中可以模拟多种响应.步骤如下: 1.添加断点方法有两种: 方法1:找到Charles中菜单项Pr ...
- [LuoguP1264]K-联赛_网络流
K-联赛 题目链接:https://www.luogu.org/problem/P1264 数据范围:略. 题解: 首先,枚举所有球队是否作为答案是必须的. 因为发现$n$实在是特别小,很容易想到网络 ...
- ssm+reids缓存整合
在说正文之前我们先介绍一下redis: redis是当今比较热门的非关系型数据库之一,他使用的是key-value的键值对来进行存储,是一个存在于内存之中的数据库,我们一般用于做数据缓存.当我们需要大 ...
- 高深的dp POJ 2229Sumsets
对于这个问题, 我们显然可以看出来, 当他是奇数的时候, 直接等于他的前一个偶数 dp [ i ] = dp [ i - 1] ; 那么问题, 当它是偶数的时候, 我们应该怎么进行 dp 记忆化搜索并 ...
- dp 状态压缩
之前我们在讨论的dp形式当中, 大多数是对整数的动态规划, 然而对于集合而言呢 ? 我们使用 DFS 吗, 看起来也可以, 但是加上dp记忆 数组的 动态规划效率更高: 那么进一步讨论, 我们如何表示 ...
- 剑指offer17:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
1 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 2 思路和方法 (1)先在A中找和B的根节点相同的结点 (2)找到之后遍历对应位置的其他结点, ...
- ios 输入框失去焦点,位置回调方法
微信网页开发,ios 在input,textarea 失去焦点后,页面无法回调. 以下方法可解决: $("input,textarea").on("blur", ...
- 基于DNS(Consul)高可用
DNS 推荐从Bind-DLZ入手,资料多可控制度更好(查询DNS记录SQL可定制)据说性能差 Bind-DLZhttps://www.cnblogs.com/saneri/p/8178065.htm ...
- VSFTP添加用户
VSFTPD的安装网上有很多教程这里就不多说了,这里主要是针对做主机空间服务的朋友在安装好vsftpd后如何为用户增加ftp账号 先来看一看我们一般在*inux系统下面如何增加用户的 #adduser ...
- LeetCode 899. Orderly Queue
899. Orderly Queue(有序队列) 题目: 给出了一个由小写字母组成的字符串 S.然后,我们可以进行任意次数的移动. 在每次移动中,我们选择前 K 个字母中的一个(从左侧开始),将其从原 ...