C. Subset Sums
time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an array a1, a2, ..., an and m sets S1, S2, ..., Sm of indices of elements of this array. Let's denote Sk = {Sk, i} (1 ≤ i ≤ |Sk|). In other words, Sk, i is some element from set Sk.

In this problem you have to answer q queries of the two types:

  1. Find the sum of elements with indices from set Sk: . The query format is "? k".
  2. Add number x to all elements at indices from set Sk: aSk, i is replaced by aSk, i + x for all i (1 ≤ i ≤ |Sk|). The query format is "+ k x".

After each first type query print the required sum.

Input

The first line contains integers n, m, q (1 ≤ n, m, q ≤ 105). The second line contains n integers a1, a2, ..., an (|ai| ≤ 108) — elements of array a.

Each of the following m lines describes one set of indices. The k-th line first contains a positive integer, representing the number of elements in set (|Sk|), then follow |Sk| distinct integers Sk, 1, Sk, 2, ..., Sk, |Sk| (1 ≤ Sk, i ≤ n) — elements of set Sk.

The next q lines contain queries. Each query looks like either "? k" or "+ k x" and sits on a single line. For all queries the following limits are held: 1 ≤ k ≤ m, |x| ≤ 108. The queries are given in order they need to be answered.

It is guaranteed that the sum of sizes of all sets Sk doesn't exceed 105.

Output

After each first type query print the required sum on a single line.

Please, do not write the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

Examples
Input
5 3 5
5 -5 5 1 -4
2 1 2
4 2 1 4 5
2 2 5
? 2
+ 3 4
? 1
+ 2 1
? 2
Output
-3
4
9
【分析】一开始也想到了分块,但是一直以为是线段树,所以想歪了,然后看了网上的题解。。。太强了。

设B = sqrtn

先给集合分成两种, 一种是大小大于B的, 称为重集合, 小于的称为轻集合。

显然重集合的个数不会超过B个。

对每个集合, 求出它和每个重集合交集的大小, 即cnt[i][j]表示第i个集合和第j 个重集合交集的大小。 cnt数组可以O(NB)求出

对每个重集合, 维护add和sum, add表示加在这个集合上的值, sum表示这个集合没有加上其他重集合的附加值的和。

然后把操作分为4种:

1. 在轻集合上加值。 这样对每个轻集合里面的元素暴力加上v就行(O(B))。 同时要维护重集合的sum, 于是, 每个重集合的sum加上v*cnt[i][j],(O(B))。复杂度(O(B))。

2. 在重集合上加值。 直接在重集合的add上加上v。 (O(1))

3. 询问轻集合。 ans 加上轻集合里面的元素的值, (O(B))。 然后再加上重集合的add[j] * cnt[i][j], (O(B))。 O(B)

4. 询问重集合。 ans 加上重集合的sum, 然后再加上各个重集合的add[j] * cnt[i][j]。 O(B)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
typedef long long ll;
using namespace std;
const int N = 1e5+;
const int M = ;
int n,m,q,k;
int cnt[][N],id[N],tot=;
int is[N];
ll a[N],add[N],sum[N];
vector<int>g[N],bl[N],big;
int main() {
int u,v;
scanf("%d%d%d",&n,&m,&q);
int b=sqrt(n);
for(int i=;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=;i<=m;i++){
scanf("%d",&k);
if(k>b)id[i]=++tot,big.pb(id[i]),is[i]=;;
for(int j=;j<k;j++){
scanf("%d",&u); g[i].pb(u);
if(k>b)bl[u].pb(tot),sum[tot]+=a[u];;
}
}
for(int i=;i<=m;i++){
for(int j=;j<g[i].size();j++){
int u=g[i][j];
for(int p=;p<bl[u].size();p++){
cnt[bl[u][p]][i]++;
}
}
}
char str[];
while(q--){
scanf("%s",str);
if(str[]=='+'){
scanf("%d%d",&u,&v);
if(is[u]){
add[id[u]]+=v;
}
else {
for(int i=;i<g[u].size();i++){
int c=g[u][i];
a[c]+=v;
}
for(int i=;i<big.size();i++){
int c=big[i];
sum[c]+=v*cnt[c][u];
}
}
}
else {
scanf("%d",&u);
if(is[u]){
ll ans=sum[id[u]];
for(int i=;i<big.size();i++){
int c=big[i];
ans+=add[c]*cnt[c][u];
}
printf("%lld\n",ans);
}
else {
ll ans=;
for(int i=;i<g[u].size();i++){
ans+=a[g[u][i]];
}
for(int i=;i<big.size();i++){
int c=big[i];
ans+=add[c]*cnt[c][u];
}
printf("%lld\n",ans);
}
}
}
return ;
}

CodeForces 348C Subset Sums(分块)(nsqrtn)的更多相关文章

  1. Codeforces 348C Subset Sums 分块思想

    题意思路:https://www.cnblogs.com/jianrenfang/p/6502858.html 第一次见这种思路,对于集合大小分为两种类型,一种是重集合,一种是轻集合,对于重集合,我们 ...

  2. Codeforces 348C - Subset Sums(根号分治)

    题面传送门 对于这类不好直接维护的数据结构,第一眼应该想到-- 根号分治! 我们考虑记[大集合]为大小 \(\geq\sqrt{n}\) 的集合,[小集合]为大小 \(<\sqrt{n}\) 的 ...

  3. [codeforces 509]C. Sums of Digits

    [codeforces 509]C. Sums of Digits 试题描述 Vasya had a strictly increasing sequence of positive integers ...

  4. 洛谷P1466 集合 Subset Sums

    P1466 集合 Subset Sums 162通过 308提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 对于从1到N (1 ...

  5. Project Euler 106:Special subset sums: meta-testing 特殊的子集和:元检验

    Special subset sums: meta-testing Let S(A) represent the sum of elements in set A of size n. We shal ...

  6. Project Euler P105:Special subset sums: testing 特殊的子集和 检验

    Special subset sums: testing Let S(A) represent the sum of elements in set A of size n. We shall cal ...

  7. Project Euler 103:Special subset sums: optimum 特殊的子集和:最优解

    Special subset sums: optimum Let S(A) represent the sum of elements in set A of size n. We shall cal ...

  8. Codeforces348C - Subset Sums

    Portal Description 给出长度为\(n(n\leq10^5)\)的序列\(\{a_n\}\)以及\(m(m\leq10^5)\)个下标集合\(\{S_m\}(\sum|S_i|\leq ...

  9. CodeForces 837F - Prefix Sums | Educational Codeforces Round 26

    按tutorial打的我血崩,死活挂第四组- - 思路来自FXXL /* CodeForces 837F - Prefix Sums [ 二分,组合数 ] | Educational Codeforc ...

随机推荐

  1. 【转】IBatis.Net项目数据库SqlServer迁移至Oracle

    转自:http://www.2cto.com/database/201312/265514.html 最近完成了一个(IBatis.Net+MVC)项目的数据库+代码迁移工作,可把我折腾得~~~ IB ...

  2. AtCoder Code Festival 2017 Team Relay J - Indifferent

    题目大意:共$2n$个价格$p_i$.两人轮流取.你每次取最大的,对方每次随机取.问你取的期望和是多少. 题解:从小到大排序,$\sum\limits_{i=0}^{2n-1} \frac{i*p_i ...

  3. clique 解题报告

    clique 题目描述 数轴上有 \(n\) 个点,第 \(i\) 个点的坐标为 \(x_i\),权值为 \(w_i\).两个点 \(i\),\(j\) 之间存在一条边当且仅当 \(abs(x_i-x ...

  4. jocky1.0.3 (原joc) java混淆器 去除jdk版本限制

    昨晚下班回去,研究了下jocky1.0.3的使用,发现编译时提示引用类库版本不对,捣弄了半个小时后终于理解,原来是我的jdk1.7版本过高,这货是06年的版本,到现在都没更新过,支持(限制)的最高版本 ...

  5. makefile使用笔记(一)入门

    By francis_hao    Mar 2,2017 makefile makefile一个很简单的例子如下,该实例完成在执行make时,将main.c编译成可执行文件main的功能. 各项的含义 ...

  6. 2018 BAT最新 php面试必考题

    收集一些实用php面试题及答案给大家 做为程序员,到IT企业面试的时候肯定会有笔试这关,那就要考考你的PHP知识了,所以本站收集一些实用的php面试题及答案给大家.  基础题:  1.表单中 get与 ...

  7. 用spring的@Validated注解和org.hibernate.validator.constraints.*的一些注解在后台完成数据校验

    这个demo主要是让spring的@Validated注解和hibernate支持JSR数据校验的一些注解结合起来,完成数据校验.这个demo用的是springboot. 首先domain对象Foo的 ...

  8. 在linux环境下让java代码生效的步骤

    1.kill jboss 2.compile 3.deploy 4.bootstrap jboss.

  9. bzoj 4836 [Lydsy1704月赛]二元运算 分治FFT+生成函数

    [Lydsy1704月赛]二元运算 Time Limit: 8 Sec  Memory Limit: 128 MBSubmit: 577  Solved: 201[Submit][Status][Di ...

  10. git上传本地项目

    1.(先进入项目文件夹)通过命令 git init 把这个目录变成git可以管理的仓库 git init 2.把文件添加到版本库中,使用命令 git add .添加到暂存区里面去,不要忘记后面的小数点 ...