Codeforces 296C Greg and Array

数据结构题。个人认为是比较好的数据结构题。题意:给定一个长度为n的数组a,然后给定m个操作序列,每个操作:l, r, x将区间[l, r]内的元素都增加a,然后有k个查询,查询形式是对于操作序列x,y是将第x个操作到第y个操作执行一遍。然后求最后的数组的元素值。

1.线段树解法:维护两棵线段树,一棵用于维护执行的操作序列的执行次数,一棵用于维护数组a的值。复杂度O(nlogn)。

2.扫描区间。对于数组和操作序列分别维护一个数组lx[],ly[]。ly[i]表示区间[i, m]中每个操作执行的次数,lx[i]表示区间[i, n]中每个数的增量的值。O(n)的复杂度。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define maxn 100005
 4 #define lson(c) (c<<1)
 5 #define rson(c) (c<<1|1)
 6 #define mid(x, y) ((x+y)>>1)
 7 typedef long long LL;
 8 
 9 struct Tree{
10     LL f[maxn*4];
11     Tree(){
12         memset(f, 0, sizeof(f));
13     }
14     void init(){
15         memset(f, 0, sizeof(f));
16     }
17     void push_down(int c){
18         int l = lson(c), r = rson(c);
19         f[l] += f[c];
20         f[r] += f[c];
21         f[c] = 0;
22     }
23     void update(int l, int r, int c, int lp, int rp, LL d){
24         if(lp <= l && r <= rp){
25             f[c] += d;
26             return ;
27         }
28         push_down(c);
29         int m = mid(l, r);
30         if(rp <= m) update(l, m, lson(c), lp, rp, d);
31         else if(lp > m) update(m + 1, r, rson(c), lp, rp, d);
32         else{
33             update(l, m, lson(c), lp, m, d);
34             update(m+1, r, rson(c), m+1, rp, d);
35         }
36     }
37     void query(int c, int l, int r, LL a[], int s){
38         if(l==r){
39             if(s)
40                 a[l] = a[l]*f[c];
41             else a[l] = a[l] + f[c];
42             return ;
43         }
44         push_down(c);
45         int mid = mid(l, r);
46         query(lson(c), l, mid, a, s);
47         query(rson(c), mid+1, r, a, s);
48     }
49 }insTree, arrTree;
50 LL a[maxn], ind[maxn];
51 int ls[maxn], rs[maxn];
52 
53 int main(){
54     //freopen("test.in", "r", stdin);
55     for(int n, m, k; scanf("%d%d%d", &n, &m, &k)!=EOF; ){
56         insTree.init();
57         arrTree.init();
58         for(int i = 1; i <= n; i ++){
59             scanf("%I64d", &a[i]);
60         }
61         for(int i = 1; i <= m; i ++){
62             scanf("%d %d %I64d", &ls[i], &rs[i], &ind[i]);
63         }
64         for(int i = 1, x, y; i <= k; i ++){
65             scanf("%d%d", &x, &y);
66             insTree.update(1, m, 1, x, y, 1);
67         }
68         insTree.query(1, 1, m, ind, 1);
69         for(int i = 1; i <= m; i ++){
70             arrTree.update(1, n, 1, ls[i], rs[i], ind[i]);
71         }
72         arrTree.query(1, 1, n, a, 0);
73         for(int i = 1; i <= n; i ++){
74             printf("%I64d ", a[i]);
75         }
76         printf("\n");
77     }
78 }
View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 #define maxn 100005
 4 typedef long long LL;
 5 LL a[maxn], ind[maxn];
 6 LL lx[maxn], ly[maxn];
 7 int px[maxn], py[maxn];
 8 
 9 int main(){
10     //freopen("test.in", "r", stdin);
11     for(int n, m, k; scanf("%d%d%d", &n, &m, &k)!=EOF; ){
12         memset(lx, 0, sizeof(lx));
13         memset(ly, 0, sizeof(ly));
14         for(int i = 1; i <= n; i ++) scanf("%I64d", &a[i]);
15         for(int i = 1; i <= m; i ++) scanf("%d%d%I64d", &px[i], &py[i], &ind[i]);
16         for(int i = 1, x, y; i <= k; i ++){
17             scanf("%d%d", &x, &y); lx[x] += 1, lx[y+1] -= 1;
18         }
19         LL s = 0;
20         for(int i = 1; i <= m; i ++){
21             s += lx[i];
22             ind[i] = ind[i] *s;
23         }
24         for(int i = 1; i <= m; i ++){
25             ly[px[i]] += ind[i];
26             ly[py[i]+1] -= ind[i];
27         }
28         s = 0;
29         for(int i = 1; i <= n; i ++){
30             s += ly[i];
31             printf("%I64d ", a[i] + s);
32         }
33         printf("\n");
34     }
35     return 0;
36 }
View Code
原文地址:https://www.cnblogs.com/bootstar/p/3206313.html