SegmentTreeNode<T,V> Query(int low, int high, int left, int right, int curindex = 1) { //cout<<"left : "<<left<<" right : "<<right<<" Curindex : "<<curindex<<" low: "<<low<<" high: "<<high<<endl; if (low == left && high == right) return Tree[curindex]; else { int mid = (left+right)/2; if (low > mid) return Query(low,high,mid+1,right,2*curindex+1); else if(high <= mid) return Query(low, high, left, mid, 2*curindex); else if(low <= mid && high >= mid) { SegmentTreeNode<T,V> node; return node.mergeforquery(Query(low,mid,left,mid,2*curindex),Query(mid+1,high,mid+1,right,2*curindex+1)); } else { SegmentTreeNode<T,V> node; node.assigninitialvalues(0); return node; } } }
int query(int lo, int hi) { // [lo,hi]와 [first,last]의 교집합이 없는 경우 if(hi < first || last < lo) return -1; // [lo,hi]가 [first,last]를 포함하는 경우 if(lo <= first && last <= hi) return max_value; // 이외의 경우 각각 나눠 최대값 찾고, 최대치를 반환 return max(left->query(lo, hi), right->query(lo, hi)); }
int query(int l, int r) { if (l <= min && r >= max) { return value; } else { return (left ? left->query(l, r) : 0) + (right ? right->query(l, r) : 0); } }
SegmentTreeNode getValue(int index, int left, int right, int lo, int hi){ if(left==lo && right==hi) return nodes[index]; int mid = (left+right)/2; if(mid<lo) return getValue(2*index+1,mid+1,right,lo,hi); if(hi<=mid)return getValue(2*index,left,mid,lo,hi); SegmentTreeNode l = getValue(2*index, left, mid, lo, mid); SegmentTreeNode r = getValue(2*index+1,mid+1,right, mid+1, hi); SegmentTreeNode ret; ret.merge(l,r); return ret; }
SegmentTreeNode mergeforquery(SegmentTreeNode node1, SegmentTreeNode node2) { SegmentTreeNode<T,V> node; node.assigninitialvalues(); // The OPeration to make the // Statistic into order. node.sum = node1.sum+node2.sum; node.lsum = max(node1.lsum,node1.sum+node2.lsum); node.rsum = max(node2.rsum,node2.sum+node1.rsum); node.result = max(node1.rsum + node2.lsum,max(node1.result,node2.result)); return node; }
/** * @param A: An integer array * @return: The number of element in the array that * are smaller that the given integer */ vector<int> countOfSmallerNumber(vector<int> &A, vector<int> &queries) { // write your code here SegmentTreeNode *root = new SegmentTreeNode(0, 2000); for (size_t i = 0; i < A.size(); ++ i) { root->add(A[i]); } vector<int> count_list; for (size_t i = 0; i < queries.size(); ++ i) { count_list.push_back(root->query(0, queries[i])); } return count_list; }
void update(int pos, int value) { // 터미널 노드인 경우 값을 바로 업데이트 if(first == last) max_value = value; // 아닌 경우 적절한 가지에 값을 전파하고 구간 최대값을 업데이트 else { if(pos <= (first + last) / 2) left->update(pos, value); else right->update(pos, value); max_value = max(left->max_value, right->max_value); } }
void initializebysize(int N) { int size = 1,i; for (; size < N; size<<=1); size<<=1; sizeoftree = size; for (i = 0; i < size; ++i) { SegmentTreeNode<T,V> node; node.assigninitialvalues(); Tree.push_back(node); } }
void add(int num) { if (num < min || num >= max) { return; } //cout << "debug " << num << " (" << min << ", " << max << ")" << endl; ++ value; if (left) { left->add(num); } if (right) { right->add(num); } }
SegmentTreeNode getValue(int stIndex, int left, int right, int lo, int hi) { if (left == lo && right == hi) return nodes[stIndex]; int mid = (left + right) / 2; if (lo > mid) return getValue(2*stIndex+1, mid+1, right, lo, hi); if (hi <= mid) return getValue(2*stIndex, left, mid, lo, hi); SegmentTreeNode leftResult = getValue(2*stIndex, left, mid, lo, mid); SegmentTreeNode rightResult = getValue(2*stIndex+1, mid+1, right, mid+1, hi); SegmentTreeNode result; result.merge(leftResult, rightResult); return result; }
V getValue(int lo, int hi) { SegmentTreeNode result = getValue(1, 0, N-1, lo, hi); return result.getValue(); }
// [lo, hi] 범위의 값 중 최대값을 구한다. int query(int lo, int hi) { return root->query(lo, hi); }
// pos위치의 값을 value로 바꾼다. void update(int pos, int value) { root->update(pos, value); }