poj 3468 A Simple Problem with Integers 线段树 题解《挑战程序设计竞赛》

地址 http://poj.org/problem?id=3468 

 

线段树模板 

要背下此模板

线段树
  1 #include <iostream>
  2 #include <vector>
  3 #include <math.h>
  4 #include <algorithm>
  5 
  6 
  7 using namespace std;
  8 
  9 /*
 10 Sample Input
 11 10 5
 12 1 2 3 4 5 6 7 8 9 10
 13 Q 4 4
 14 Q 1 10
 15 Q 2 4
 16 C 3 6 3
 17 Q 2 4
 18 Sample Output
 19 4
 20 55
 21 9
 22 15
 23 */
 24 typedef long long ll;
 25 
 26 const int  DAT_SIZE = (1 << 18) - 1;
 27 
 28 const int MAX_N = 100000010;
 29 
 30 //输入
 31 int N, Q;
 32 int A[MAX_N];
 33 char T[MAX_N];
 34 int L[MAX_N], R[MAX_N], X[MAX_N];
 35 
 36 //线段树
 37 ll dat_a[DAT_SIZE], dat_b[DAT_SIZE];
 38 
 39 //对区间[a,b]同时加x
 40 //k是节点的编号 对应的空间是[l,r)
 41 void add(int a, int b, int x, int k, int l, int r)
 42 {
 43     if (a <= l && r <= b) {
 44         dat_a[k] += x;
 45     }
 46     else if (l < b && a < r) {
 47         dat_b[k] += (min(b,r)-max(a,l))* x;
 48         add(a, b, x, k * 2 + 1, l, (l + r) / 2);
 49         add(a, b, x, k * 2 + 2, (l + r) / 2, r);
 50     }
 51 }
 52 
 53 //计算[a,b)的和
 54 //k是节点的编号 对应的区间是[l,r)
 55 ll sum(int a, int b, int k, int l, int r)
 56 {
 57     if (b <= l || r <= a) {
 58         return 0;
 59     }
 60     else if(a <= l && r <= b){
 61         return dat_a[k] * (r - l) + dat_b[k];
 62     }
 63     else {
 64         ll res = (min(b,r)-max(a,l)) * dat_a[k];
 65         res += sum(a, b, k * 2 + 1, l, (l + r) / 2);
 66         res += sum(a, b, k * 2 + 2, (l + r) / 2, r);
 67         return res;
 68     }
 69 }
 70 
 71 void solve()
 72 {
 73     for (int i = 0; i < N; i++) {
 74         add(i, i + 1, A[i], 0, 0, N);
 75     }
 76     for (int i = 0; i < Q; i++) {
 77         if (T[i] == 'C') {
 78             add(L[i]-1, R[i] , X[i], 0, 0, N);
 79         }
 80         else {
 81             printf("%lld\n",sum(L[i]-1,R[i],0,0,N));
 82         }
 83     }
 84 }
 85 
 86 
 87 
 88 int main()
 89 {
 90     cin >> N >> Q;
 91 
 92     for (int i = 0; i < N; i++) {
 93         cin >> A[i];
 94     }
 95 
 96     for (int i = 0; i < Q; i++) {
 97         cin >> T[i];
 98         if (T[i] == 'C')
 99             cin >> L[i] >> R[i] >> X[i];
100         else
101             cin >> L[i] >> R[i];
102     }
103 
104     solve();
105 
106     return 0;
107 }

 

  1 #include <iostream>
  2 #include <vector>
  3 
  4 
  5 using namespace std;
  6 
  7 /*
  8 Sample Input
  9 10 5
 10 1 2 3 4 5 6 7 8 9 10
 11 Q 4 4
 12 Q 1 10
 13 Q 2 4
 14 C 3 6 3
 15 Q 2 4
 16 Sample Output
 17 4
 18 55
 19 9
 20 15
 21 */
 22 
 23 typedef long long ll;
 24 
 25 int n, m;
 26 
 27 const int MAX_N  = 1000010;
 28 int input[MAX_N];
 29 
 30 struct Node {
 31     int l, r;
 32     ll data;
 33 };
 34 
 35 struct Node stree[MAX_N * 4];
 36 
 37 
 38 void build(int idx, int l, int r)
 39 {
 40     stree[idx].l = l;
 41     stree[idx].r = r;
 42     if (l == r) {
 43         //叶子节点
 44         stree[idx].data = input[l];
 45         return;
 46     }
 47 
 48     int mid = (l + r) / 2;
 49     build(idx * 2, l,mid);
 50     build(idx * 2 + 1, mid + 1, r);
 51 
 52     stree[idx].data = stree[idx * 2].data + stree[idx * 2 + 1].data;
 53 }
 54 
 55 ll query(int idx, int start, int end, int l, int r)
 56 {
 57     if (l == stree[idx].l && r == stree[idx].r) {
 58         return stree[idx].data;
 59     }
 60 
 61     int mid = (start + end) / 2;
 62     if (l <= mid && r <= mid) {
 63         return query(idx * 2, start, mid, l, r);
 64     }
 65     else if (l > mid && r > mid) {
 66         return query(idx * 2 + 1, mid + 1, end, l, r);
 67     }
 68     else {
 69         ll res = 0;
 70         res += query(idx * 2 , start, mid, l, mid);
 71         res += query(idx * 2 + 1, mid + 1, end, mid + 1, r);
 72         return res;
 73     }
 74 
 75 }
 76 
 77 void add(int idx, int l, int r, int v)
 78 {
 79     if (l == r && stree[idx].l == stree[idx].r && stree[idx].l == l) {
 80         //叶子节点
 81         stree[idx].data += v;
 82         return;
 83     }
 84 
 85     int mid = (stree[idx].l + stree[idx].r) / 2;
 86     if (l <= mid && r <= mid) {
 87         add(idx * 2, l, r,v);
 88     }
 89     else if (l > mid && r > mid) {
 90         add(idx * 2 + 1, l, r,v);
 91     }
 92     else {
 93         add(idx * 2 , l, mid, v);
 94         add(idx * 2 + 1, mid+1, r, v);
 95     }
 96 
 97     stree[idx].data = stree[idx*2].data + stree[idx*2+1].data;
 98 }
 99 
100 
101 
102 int main()
103 {
104     int n, m;
105     cin >> n >> m;
106     for (int i = 1; i <= n; i++) {
107         cin >> input[i];
108     }
109 
110     build(1, 1, n);
111 
112     for (int i = 0; i < m; i++) {
113         char t;
114         int l, r, v;
115         cin >> t;
116         if (t == 'C') {
117             cin >> l >> r >> v;
118             add(1, l, r, v);
119         }
120         else if (t == 'Q') {
121             cin >> l >> r;
122             cout << query(1, 1, n, l, r) << endl;
123         }
124     }
125 
126 
127     return 0;
128 }
自写TLE代码

 

posted on 2019-12-12 17:10  itdef  阅读(335)  评论(0编辑  收藏  举报

导航