LINTCODE——区间求和II
思路:线段树的构造,线段树的查询,线段树的修改的结合版,三个程序拼接再一起就是这个题目的解法了,和统计前面比自己小的数的个数一样
class Solution {
class SegmentTreeNode{
public:
int start, end;
long long count;
SegmentTreeNode *left, *right;
SegmentTreeNode(int start, int end, int count) {
this->start = start;
this->end = end;
this->count = count;
this->left = this->right = NULL;
}
};
private:
SegmentTreeNode *root;
public:
/* you may need to use some attributes here */
/*
* @param A: An integer array
*/
Solution(vector<int> A) {
// do intialization if necessary
root = build(0,A.size()-1);
for(int i = 0; i<A.size(); i++)
{
modify(i, A[i]);
}
}
/*
* @param start: An integer
* @param end: An integer
* @return: The sum from start to end
*/
long long query(int start, int end) {
// write your code here
return query(root, start, end);
}
long long query(SegmentTreeNode *root, int start, int end)
{
if(root == NULL || start > end)
return 0;
if(start <= root -> start && end >= root -> end)
return root -> count;
int mid = (root -> start + root -> end)/2;
if(start > mid)
return query(root -> right , start, end);
else if(end < mid +1)
return query(root -> left ,start ,end);
else
return( query(root->left, start ,mid) + query(root -> right , mid +1,end) );
}
/*
* @param index: An integer
* @param value: An integer
* @return: nothing
*/
void modify(int index, int value) {
// write your code here
modify(root, index, value);
}
void modify(SegmentTreeNode *root, int index, int value)
{
if(root == NULL || index < root -> start || index > root -> end)
return;
if(root->start == index && root -> end == index)
{
root -> count = value;
return;
}
else
{
int mid = (root -> start + root -> end)/2;
if(index > mid )
modify(root->right, index, value);
else
modify(root->left, index, value);
}
//root的值等于左节点加右节点
root -> count = root->left->count + root->right->count;
return;
}
SegmentTreeNode *build(int start, int end) {
// write your code here
if(start > end)
return NULL;
SegmentTreeNode *root = new SegmentTreeNode(start,end,0);
if(start == end)
{
root->left = root -> right = NULL;
return root;
}
root->left = build(root->start,(root->start+root->end)/2);
root->right= build((root->start+root->end)/2+1 , root -> end);
return root;
}
};