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 ;
}

最新文章

  1. 在ASP.NET 5项目中使用和调试外部源代码包
  2. 20145304 Java第八周学习报告
  3. java面试核心基础(1)
  4. Solr入门之SolrServer实例化方式
  5. 每天一个Linux命令(01)--ls命令
  6. HTML学习 框架
  7. HADOOP集群配置
  8. 识别你的ADFS是什么版本的(Which version of ADFS is running)
  9. dummy_backend_queue.go
  10. functools 之 partial(偏函数)
  11. day11 函数的位置形参,位置实参,可变长位置形参,关键字形参
  12. 0.1Linux系统开发Angular项目一一首次运行环境的安装(chrome ,terminator,git,node)
  13. SQL语句:Mac 下 处理myql 不能远程登录和本地登录问题
  14. Linux中几个与文档相关的命令
  15. B/S模式实现批量打包apk
  16. SpingBoot二——引入MySql数据库
  17. QR分解与最小二乘
  18. iOS开发之工具篇-20个可以帮你简化移动app开发流程的工具
  19. 关于eclipse没有js、xml代码提示的解决:下载一个插件
  20. HDU - 5327 Olympiad(一维前缀和)

热门文章

  1. [洛谷P1879][USACO06NOV]玉米田Corn Fields
  2. 【BZOJ 3195 】[Jxoi2012]奇怪的道路 装压dp
  3. 如何使用Eclipse调试framework
  4. 使用记事本创建Web服务(WebService)
  5. git上传本地项目
  6. 关于MyBatis的collection集合中只能取到一条数据的问题
  7. bzoj 2753 最小生成树变形
  8. Makefile 的 prequisite 執行順序 single multi thread
  9. 【 HAProxy 】学习笔记
  10. django定义模型类