1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| #include <cstdio> #include <vector> #include <cmath> #define int long long #define set wtcl
int a[100005], cnt[100005][350], id[100005]; int sum[100005], Lazy[100005], S, tot; std::vector<int> set[100005], num[100005], unionset[100005]; bool mark[100005][350];
signed main() { int n, m, q; scanf("%lld%lld%lld", &n, &m, &q); S = sqrt(n); for (int i = 1; i <= n; ++ i) scanf("%lld", a + i); for (int i = 1; i <= m; ++ i) { int k, x; scanf("%lld", &k); if (k > S) id[i] = ++ tot; while (k --) { scanf("%lld", &x); set[i].push_back(x); if (id[i]) num[x].push_back(i), sum[id[i]] += a[x]; } } for (int i = 1; i <= m; ++ i) for (int j : set[i]) for (int k : num[j]) { if (!mark[i][id[k]]) { mark[i][id[k]] = true; unionset[i].push_back(id[k]); } ++ cnt[i][id[k]]; } while (q --) { char opt; int k, x; scanf(" %c", &opt); if (opt == '?') { scanf("%lld", &k); int ans = 0; if (set[k].size() <= S) { for (int i : set[k]) ans += a[i]; for (int i : unionset[k]) ans += cnt[k][i] * Lazy[i]; } else { ans = sum[id[k]]; for (int i = 1; i <= tot; ++ i) ans += cnt[k][i] * Lazy[i]; } printf("%lld\n", ans); } else { scanf("%lld%lld", &k, &x); if (set[k].size() <= S) { for (int i : set[k]) a[i] += x; for (int i : unionset[k]) sum[i] += cnt[k][i] * x; } else Lazy[id[k]] += x; } } return 0; }
|