hihoCoder#1078 线段树的区间修改

原题地址

 

提示给的伪代码非常赞?,按照提示做,难度为0

代码写的偏工程风,果然冗长了许多_(:з」∠)_

 

代码:

  1 #include <iostream>
  2 
  3 using namespace std;
  4 
  5 #define MAX_NODE 100008
  6 
  7 struct TreeNode {
  8   int leftBound;
  9   int rightBound;
 10   TreeNode *leftChild;
 11   TreeNode *rightChild;
 12   int lazyTag;
 13   int priceSum;
 14   int length;
 15 
 16   TreeNode(int lb, int rb, TreeNode *lc, TreeNode *rc, int ps)
 17     : leftBound(lb),
 18       rightBound(rb),
 19       leftChild(lc),
 20       rightChild(rc),
 21       lazyTag(-1),
 22       priceSum(ps) {
 23     length = rightBound - leftBound + 1;
 24   }
 25 };
 26 
 27 int N, Q;
 28 int p[MAX_NODE];
 29 
 30 void remove(TreeNode *root) {
 31   if (root->leftChild)
 32     remove(root->leftChild);
 33   if (root->rightChild)
 34     remove(root->rightChild);
 35   delete root;
 36 }
 37 
 38 TreeNode *build(int leftBound, int rightBound) {
 39   if (leftBound == rightBound)
 40     return new TreeNode(leftBound, rightBound, NULL, NULL, p[leftBound]);
 41 
 42   TreeNode *leftChild = build(leftBound, (leftBound + rightBound) / 2);
 43   TreeNode *rightChild = build((leftBound + rightBound) / 2 + 1, rightBound);
 44 
 45   return new TreeNode(leftBound, rightBound, leftChild, rightChild, leftChild->priceSum + rightChild->priceSum);
 46 }
 47 
 48 void modify(TreeNode *root, int leftBound, int rightBound, int price) {
 49   if (root->leftBound == leftBound && root->rightBound == rightBound) {
 50     root->lazyTag = price;
 51     root->priceSum = root->length * price;
 52     return;
 53   }
 54 
 55   if (root->lazyTag != -1) {
 56     root->leftChild->lazyTag = root->lazyTag;
 57     root->leftChild->priceSum = root->leftChild->length * root->lazyTag;
 58 
 59     root->rightChild->lazyTag = root->lazyTag;
 60     root->rightChild->priceSum = root->rightChild->length * root->lazyTag;
 61 
 62     root->lazyTag = -1;
 63   }
 64 
 65   int middle = (root->leftBound + root->rightBound) / 2;
 66   if (rightBound <= middle)
 67      modify(root->leftChild, leftBound, rightBound, price);
 68   else if (leftBound > middle)
 69      modify(root->rightChild, leftBound, rightBound, price);
 70   else {
 71     modify(root->leftChild, leftBound, middle, price);
 72     modify(root->rightChild, middle + 1, rightBound, price);
 73   }
 74 
 75   root->priceSum = root->leftChild->priceSum + root->rightChild->priceSum;
 76 }
 77 
 78 int query(TreeNode *root, int leftBound, int rightBound) {
 79   if (root->leftBound == leftBound && root->rightBound == rightBound)
 80     return root->priceSum;
 81 
 82   if (root->lazyTag != -1) {
 83     root->leftChild->lazyTag = root->lazyTag;
 84     root->leftChild->priceSum = root->leftChild->length * root->lazyTag;
 85 
 86     root->rightChild->lazyTag = root->lazyTag;
 87     root->rightChild->priceSum = root->rightChild->length * root->lazyTag;
 88 
 89     root->lazyTag = -1;
 90   }
 91 
 92   int middle = (root->leftBound + root->rightBound) / 2;
 93   int priceSum = 0;
 94   if (rightBound <= middle)
 95     priceSum += query(root->leftChild, leftBound, rightBound);
 96   else if (leftBound > middle)
 97     priceSum += query(root->rightChild, leftBound, rightBound);
 98   else {
 99     priceSum += query(root->leftChild, leftBound, middle);
100     priceSum += query(root->rightChild, middle + 1, rightBound);
101   }
102 
103   return priceSum;
104 }
105 
106 int main() {
107   scanf("%d", &N);
108   for (int i = 0; i < N; i++)
109     scanf("%d", &(p[i]));
110 
111   TreeNode *root = build(0, N - 1);
112 
113   scanf("%d", &Q);
114   while (Q--) {
115     int t;
116     scanf("%d", &t);
117     if (t) {
118       int l, r, v;
119       scanf("%d%d%d", &l, &r, &v);
120       modify(root, l - 1, r - 1, v);
121     }
122     else {
123       int l, r;
124       scanf("%d%d", &l, &r);
125       printf("%d\n", query(root, l - 1, r - 1));
126     }
127   }
128 
129   remove(root);
130 
131   return 0;
132 }

 

转载于:https://www.cnblogs.com/boring09/p/4385590.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值