CodeForces 348C Subset Sums nsqrtn的姿势。。
来源:互联网 发布:歧视 知乎 编辑:程序博客网 时间:2024/06/06 17:32
题意:
给n个数和m个集合, 一个集合就是n个数的下标。
有q个操作, 每个操作就是给一个集合里面代表的数加上v, 或者询问一个集合里面的数的和。
解法:
ORZ题解。。。
设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 <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <vector>using namespace std;#define mnx 110020#define B 350#define LL long long#define PB push_back#define vi vector<int>LL add[B], sum[B];int id[mnx]; //第i个集合的重集合标号int cnt[mnx][B], c[mnx];LL tot[mnx];bool h[mnx]; // 第i个集合是不是重集合vi g[mnx]; //集合vi t[mnx]; // 第i个数被哪些重集合包括int n, m, q, k;int main() {while(scanf("%d%d%d", &n, &m, &q) != EOF) {for(int i = 0; i < n; ++i) scanf("%I64d", &tot[i]);k = 0;for(int i = 0; i < m; ++i) {scanf("%d", &c[i]);if(c[i] >= B) {h[i] = 1;id[i] = k++;}else h[i] = 0;for(int j = 0; j < c[i]; ++j) {int u;scanf("%d", &u);--u;g[i].PB(u);if(h[i]) { // 重集合的话在包括u的重集合中加上k-1t[u].PB(k - 1);sum[k-1] += tot[u];}}}//memset(cnt, 0, sizeof cnt);for(int i = 0; i < m; ++i) {for(int j = 0; j < g[i].size(); ++j) {int u = g[i][j]; //第i个集合包含的下标for(int kk = 0; kk < t[u].size(); ++kk) {int v = t[u][kk]; //重集合cnt[i][v]++;}}}while(q--) {char op[4];int p;LL x;scanf("%s%d", op, &p);--p;if(op[0] == '?') {LL ans = 0;if(h[p]) {ans += sum[id[p]];for(int i = 0; i < k; ++i)ans += cnt[p][i] * add[i];}else {for(int i = 0; i < g[p].size(); ++i) {ans += tot[g[p][i]];}for(int i = 0; i < k; ++i)ans += cnt[p][i] * add[i];}printf("%I64d\n", ans);}else {scanf("%I64d", &x);if(h[p]) {add[id[p]] += x;}else {for(int i = 0; i < g[p].size(); ++i)tot[g[p][i]] += x;for(int i = 0; i < k; ++i)sum[i] += cnt[p][i] * x;}}}}return 0;}
0 0
- CodeForces 348C Subset Sums nsqrtn的姿势。。
- 乱搞 [CodeForces 348C] Subset Sums nsqrtn
- CodeForces 348 C.Subset Sums(分块)
- codeforces 348 C. Subset Sums (暴力+技巧)
- C. Subset Sums----分桶法
- Codeforces 349E - Subset Sums
- Subset Sums
- Subset Sums
- Subset Sums
- Subset Sums
- USACO 2.2 Subset Sums (subset)
- USACO2.2.2 Subset Sums (subset)
- USACO2.2.2 Subset Sums (subset)
- Section 2.2 Subset Sums
- USACO 2.2 Subset Sums
- 2.2Subset Sums
- usaco training-Subset Sums
- Subset Sums 集合
- 1037. Magic Coupon (25)
- 边记边学PHP-(九)PHP字符串常用函数及内容分页实现
- HTML中id,name,value的认识
- 关于接口可以实例化的问题
- js简易版自定义事件及其应用
- CodeForces 348C Subset Sums nsqrtn的姿势。。
- 虚拟内存的好处及多级分页机制的原因
- Tomcat配置过程中的一点小问题
- 面向对象编程的认识
- Mecanim学习笔记
- WinEdit注册破解,试用时间修改
- Unity3D研究院之Machine动画脚本自动生成AnimatorController(七十一)
- Win8.1和Centos 7双系统, 磁盘挂在问题,Unable to access “ *** Volume”
- linux下编译新内核,解决无法找到eth0设备问题,安装eth0网卡驱动