Codeforces Round#179(Div 2)C Greg and Array
2013-04-12 11:09
309 查看
题目链接:http://codeforces.com/problemset/problem/295/A
我果断想错了时间复杂度,所以就没敲出来。
有两种解法,一种是线段树,两棵线段树,一棵维护每种指令用了多少次,一棵维护每段被怎么更新,时间复杂度都是nlogn级别的,可是我算错了五个数量级,昨天晚上比赛没敢写……
另一种方法是扫描法,O(n)级别,很简单,编码复杂度也比线段树解法小得多。
我果断想错了时间复杂度,所以就没敲出来。
有两种解法,一种是线段树,两棵线段树,一棵维护每种指令用了多少次,一棵维护每段被怎么更新,时间复杂度都是nlogn级别的,可是我算错了五个数量级,昨天晚上比赛没敢写……
另一种方法是扫描法,O(n)级别,很简单,编码复杂度也比线段树解法小得多。
//扫描法
#include <cstdio> #define LL long long const int maxn = 100100; LL a[maxn], b[maxn], d[maxn], ll[maxn], rr[maxn], c[maxn]; int l, r, n, m, k; int main(){ scanf("%d%d%d", &n, &m, &k); for (int i = 1; i <= n; i++) scanf("%I64d", &a[i]); for (int i = 1; i <= m; i++) scanf("%I64d%I64d%I64d", &ll[i], &rr[i], &d[i]); for (int i = 1; i <= k; i++){ scanf("%d%d", &l, &r); c[l - 1] += 1; c[r] -= 1; } LL t = 0; for (int i = 0; i <= m; i++){ d[i] *= t; t += c[i]; } t = 0; for (int i = 0; i <= m; i++){ b[ll[i] - 1] += d[i]; b[rr[i]] -= d[i]; } for (int i = 0; i <= n; i++){ a[i] += t; t += b[i]; } for (int i = 1; i<= n; i++) printf("%I64d ", a[i]); printf("\n"); return 0; }
//线段树法
#include <cstdio> #include <cstring> #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 #define LL long long const int maxn = 101000; struct seg{ LL sum[maxn << 2], add[maxn << 2]; void PushUp(int rt){ sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; } void PushDown(int rt, int m){ if (add[rt]){ add[rt << 1] += add[rt]; add[rt << 1 | 1] += add[rt]; sum[rt << 1] += add[rt] * (m - (m >> 1)); sum[rt << 1 | 1] += add[rt] * (m >> 1); add[rt] = 0; } } void build(int l, int r, int rt){ add[rt] = 0; if (l == r){ scanf("%I64d", &sum[rt]); return; } int m = (l + r) >> 1; build(lson); build(rson); PushUp(rt); } void update(int ll, int rr, LL c, int l, int r, int rt){ if (ll <= l && rr >= r){ sum[rt] += c * (r - l + 1); add[rt] += c; return; } PushDown(rt, r - l + 1); int m = (l + r) >> 1; if (ll <= m) update(ll, rr, c, lson); if (rr > m) update(ll, rr, c, rson); PushUp(rt); } LL query(int x, int l, int r, int rt){ if (l == r) return sum[rt]; PushDown(rt, r - l + 1); int m = (l + r) >> 1; if (x <= m) return query(x, lson); else return query(x, rson); } }; struct chg{ int l, r; LL d; void get(){ scanf("%d%d%I64d", &l, &r, &d); } }x[maxn]; seg a, b; int main(){ int n, m, k; while (~scanf("%d%d%d", &n, &m, &k)){ a.build(1, n, 1); memset(b.sum, 0, sizeof(b.sum)); memset(b.add, 0, sizeof(b.add)); for (int i = 1; i <= m; i++) x[i].get(); for (int i = 1; i <= k; i++){ int l, r; scanf("%d%d", &l, &r); b.update(l, r, 1, 1, m, 1); } for (int i = 1; i <= m; i++){ LL tt = b.query(i, 1, m, 1); a.update(x[i].l, x[i].r, x[i].d * tt, 1, n, 1); } for (int i = 1; i <= n; i++){ LL ans = a.query(i, 1, n, 1); printf("%I64d ", ans); } printf("\n"); } return 0; }
相关文章推荐
- Codeforces Round #179 (Div. 1)-A. Greg and Array
- Codeforces Round #179 (Div. 1) A. Greg and Array
- Codeforces Round #179 (Div. 2) C Greg and Array
- CodeForces Round #179 (295A) - Greg and Array 一个线段树做两次用
- Codeforces #179(Div 2)C Greg and Array
- Codeforces Round #251 (Div. 2) C. Devu and Partitioning of the Array
- 【Codeforces Round 331 (Div 2)B】【水题 贪心】Wilbur and Array 修改对p位置后的所有位置生效 最少修改次数使得数列变成b
- Codeforces Round #136 (Div. 1) B. Little Elephant and Array
- Codeforces Round #312 (Div. 2) B. Amr and The Large Array
- Codeforces Round #331 (Div. 2)-Wilbur and Array(贪心模拟)
- Codeforces Round 374 (Div 2)D Maxim and Array 【贪心】
- Codeforces Round #373 (Div. 2) E. Sasha and Array
- Codeforces Round #179 (Div. 2) B (codeforces 296b) Yaroslav and Two Strings
- Codeforces Round #249 (Div. 2)C Devu and Partitioning of the Array
- Codeforces Round #253 (Div. 2) E. Artem and Array (思维)
- Codeforces Round #249 (Div. 2)C Devu and Partitioning of the Array
- CodeforcesRound #136 (Div. 2) D. Little Elephant andArray
- 【Codeforces Round 374 (Div 2)D】【贪心】 Maxim and Array n个数做K次±X使得乘积尽可能小
- Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings
- Codeforces Round #374 (Div. 2) D. Maxim and Array 贪心