线段树

推荐:http://blog.csdn.net/x314542916/article/details/7837276

  1 //建树 
  2  struct SgtNode {
  3     int sum, l, r, ch[2];
  4 } sgt[maxn];
  5 int sgtBuild(int l, int r) {
  6     int p = tot ++;
  7     sgt[p].l = l, sgt[p].r = r;
  8     sgt[p].sum = 0;
  9     if (l + 1 < r) {
 10         int mid = (l + r) >> 1;
 11         sgt[p].ch[0] = sgtBuild(l, mid);
 12         sgt[p].ch[1] = sgtBuild(mid, r);
 13     }
 14     return p;
 15 }
 16 //单点修改 
 17 void sgtChange(int p, int pos, int delta) {
 18     sgt[p].sum += delta;
 19     if (sgt[p].l + 1 < sgt[p].r) {
 20         int mid = (sgt[p].l + sgt[p].r)>> 1;
 21         if (pos < mid) {
 22             sgtChange(sgt[p].ch[0], pos, delta);
 23         } else {
 24             sgtChange(sgt[p].ch[1], pos, delta);
 25         }
 26     }
 27 //区间求和 
 28 int sgtSum(int p, int l, int r) {
 29     if (sgt[p].l == l && sgt[p].r == r) {
 30         return sgt[p].sum;
 31     } else {
 32         int mid = (sgt[p].l + sgt[p].r)>> 1;
 33         if (r <= mid) {
 34             return sgtSum(sgt[p].ch[0], l, r);
 35         } else if (l >= mid) {
 36             return sgtSum(sgt[p].ch[1], l, r);
 37         } else {
 38             return sgtSum(sgt[p].ch[0], l, mid) + sgtSum(sgt[p].ch[1], mid, r);
 39         }
 40     }
 41 }
 42 //给一个区间加某数字 
 43 void sgtRangeAdd(int p, int l, int r, int delta) {
 44     sgt[p].sum += delta * (r - l);
 45     if (sgt[p].l == l && sgt[p].r == r) {
 46         sgt[p].addtag += delta;
 47     } else {
 48         int mid = (sgt[p].l + sgt[p].r)>> 1;
 49         if (r <= mid) {
 50             sgtRangeAdd(sgt[p].ch[0], l, r, delta);
 51         } else if (l >= mid) {
 52             sgtRangeAdd(sgt[p].ch[1], l, r, delta);
 53         } else {
 54             sgtRangeAdd(sgt[p].ch[0], l, mid, delta);
 55             sgtRangeAdd(sgt[p].ch[1], mid, r, delta);
 56         }
 57     }
 58 }
 59 //把一段区间改为某一个数字 
 60 void update(int p) {
 61     if (sgt[p].settag != -1) {
 62         sgt[p].sum = sgt[p].settag * (sgt[p].r - sgt[p].l);
 63     } else if (sgt[p].l + 1 < sgt[p].r) {
 64         sgt[p].sum = sgt[sgt[p].ch[0]].sum + sgt[sgt[p].ch[1]].sum;
 65     }
 66 }
 67 void pushDown(int p) {
 68     if (sgt[p].settag != -1) {
 69         sgt[sgt[p].ch[0]].settag = sgt[p].settag;
 70         update(sgt[p].ch[0]);
 71         sgt[sgt[p].ch[1]].settag = sgt[p].settag;
 72         update(sgt[p].ch[1]);
 73         sgt[p].settag = -1;
 74     }
 75 }
 76 void sgtRangeSet(int p, int l, int r, int value) {
 77     if (sgt[p].l == l && sgt[p].r == r) {
 78         sgt[p].settag = value;
 79         update(sgt[p]);
 80     } else {
 81         pushDown(p);
 82         int mid = (sgt[p].l + sgt[p].r)>> 1;
 83         if (r <= mid) {
 84             sgtRangeSet(sgt[p].ch[0], l, r, value);
 85         } else if (l >= mid) {
 86             sgtRangeSet(sgt[p].ch[1], l, r, value);
 87         } else {
 88             sgtRangeSet(sgt[p].ch[0], l, mid, value);
 89             sgtRangeSet(sgt[p].ch[1], mid, r, value);
 90         }
 91         update(p);
 92     }
 93 }
 94 int sgtSum(int p, int l, int r) {
 95     if (sgt[p].l == l && sgt[p].r == r) {
 96         return sgt[p].sum;
 97     } else {
 98         int mid = (sgt[p].l + sgt[p].r)>> 1;
 99         int influ = (r - l) * sgt[p].addtag;
100         if (r <= mid) {
101             return sgtSum(sgt[p].ch[0], l, r) + influ;
102         } else if (l >= mid) {
103             return sgtSum(sgt[p].ch[1], l, r) + influ;
104         } else {
105             return sgtSum(sgt[p].ch[0], l, mid) + sgtSum(sgt[p].ch[1], mid, r) + influ;
106         }
107     }
108 }
原文地址:https://www.cnblogs.com/9pounds15pence/p/6349641.html