题目连接:
题目大意:
给出n个数,有两种操作:
1:"C a b c",[a,b]中的每一个数都加上c。
2:"Q a b",求[a,b]中每个数相加的和。
解题思路:
线段树更新到每一个节点的话,由于节点数目和查询次数原因会tle,所以在每一个节点内定义一个标志变量表示当前节点的下一层为更新,每次查询时候有需要的话在更新到下一层。
1 #include2 #include 3 #include 4 #include 5 using namespace std; 6 const int maxn = 400010; 7 const int INF = 0x3f3f3f3f; 8 #define LL __int64 9 struct node 10 { 11 LL L, R; 12 LL sum, add; 13 LL Mid() 14 { 15 return (L + R) / 2; 16 } 17 }; 18 node tree[maxn]; 19 LL res; 20 21 void build(LL root, LL l, LL r) 22 { 23 tree[root].L = l; 24 tree[root].R = r; 25 tree[root].sum = tree[root].add = 0; 26 27 if (l == r) 28 return ; 29 build (2*root+1, l, tree[root].Mid()); 30 build (2*root+2, tree[root].Mid()+1, r); 31 } 32 void insert (LL root, LL s, LL e, LL x) 33 { 34 tree[root].sum += x * (e - s + 1); 35 if (tree[root].L == s && e == tree[root].R)//更新到区间 36 { 37 tree[root].add += x; 38 return ; 39 } 40 if (e <= tree[root].Mid()) 41 insert (2*root+1, s, e, x); 42 else if (tree[root].Mid() < s) 43 insert (2*root+2, s, e, x); 44 else 45 { 46 insert (2*root+1, s, tree[root].Mid(), x); 47 insert (2*root+2, tree[root].Mid()+1, e, x); 48 } 49 } 50 void query (LL root, LL s, LL e) 51 { 52 53 if (tree[root].L == s && e == tree[root].R) 54 { 55 res += tree[root].sum; 56 return ; 57 } 58 if (tree[root].add) 59 { //向下继续更新 60 tree[2*root+1].add += tree[root].add; 61 tree[2*root+2].add += tree[root].add; 62 tree[2*root+1].sum += tree[root].add * (tree[2*root+1].R - tree[2*root+1].L + 1); 63 tree[2*root+2].sum += tree[root].add * (tree[2*root+2].R - tree[2*root+2].L + 1); 64 tree[root].add = 0; 65 } 66 if (e <= tree[root].Mid()) 67 query (2*root+1, s, e); 68 else if (tree[root].Mid() < s) 69 query (2*root+2, s, e); 70 else 71 { 72 query (2*root+1, s, tree[root].Mid()); 73 query (2*root+2, tree[root].Mid()+1, e); 74 } 75 } 76 int main () 77 { 78 LL n, m, num; 79 while (scanf ("%I64d %I64d", &n, &m) != EOF) 80 { 81 build (0, 1, n); 82 for (int i=1; i<=n; i++) 83 { 84 scanf ("%I64d", &num); 85 insert (0, i, i, num); 86 } 87 char str[2]; 88 LL s, e; 89 while (m --) 90 { 91 scanf ("%s %I64d %I64d", str, &s, &e); 92 if (str[0] == 'Q') 93 { 94 res = 0; 95 query (0, s, e); 96 printf ("%I64d\n", res); 97 } 98 else 99 {100 scanf ("%I64d", &num);101 insert (0, s, e, num);102 }103 }104 }105 return 0;106 }