#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
struct node
{
int left, right;
int pos;
int mweight;
int r;
node *lchild, *rchild;
node() {
lchild = rchild = NULL;
pos = 0; // pos: mweight
mweight = 0;
r = 0;
}
};
class hpSegmentTree
{
private:
node *root;
int nodecnt;
public:
hpSegmentTree(){
root = NULL;
nodecnt = 0;
}
~hpSegmentTree(){
Clear();
}
void Clear();
int NodeCount();
void BuildSegmentTree( int, int );
void AddInterval( int, int, int );
int GetMaxInInterval( int, int, int* );
private:
void __clear( node *);
void __build( node *, int, int );
void __addInterval( node *, int, int, int );
int __getMaxInInterval( node *, int, int, int* );
void __update( node *);
};
///////////////////////////////////////////////////////////
void hpSegmentTree::Clear()
{
nodecnt = 0;
if ( root != NULL )
{
__clear( root->lchild );
__clear( root->rchild );
delete root;
root = NULL;
}
}
void hpSegmentTree::BuildSegmentTree( int left, int right )
{
root = new node();
nodecnt = 1;
__build( root, left, right );
}
int hpSegmentTree::NodeCount() { return nodecnt; }
void hpSegmentTree::AddInterval( int left, int right, int value )
{
__addInterval( root, left, right, value );
}
int hpSegmentTree::GetMaxInInterval( int left, int right, int *ret)
{
return __getMaxInInterval( root, left, right, ret );
}
/////////////////////////////////////////////////////////////
void hpSegmentTree::__clear( node *p )
{
if ( p != NULL )
{
__clear( p->lchild );
__clear( p->rchild );
delete p;
}
}
void hpSegmentTree::__build( node *p, int left, int right )
{
p->left = left;
p->right = right;
p->pos = p->left;
if ( right > left )
{
int mid = (left+right)>>1;
p->lchild = new node();
p->rchild = new node();
nodecnt += 2;
__build( p->lchild, left, mid );
__build( p->rchild, mid+1, right );
}
}
void hpSegmentTree::__addInterval( node *p, int left, int right, int value )
{
int mid = (p->left+p->right)>>1;
int r = p->r;
if ( left <= p->left && right >= p->right )
{
p->mweight += value;
p->r += value;
/*
//往下更新,其实这里在节点设置一个变量,下次查询时顺带更新!
if ( p->lchild != NULL )
{
__addInterval( p->lchild, p->left, mid, value );
__addInterval( p->rchild, mid+1, p->right, value );
}
*/
return;
}
p->lchild->mweight += r;
p->lchild->r += r;
p->rchild->mweight += r;
p->rchild->r += r;
p->r = 0;
if ( left <= mid )
__addInterval( p->lchild, left, right, value );
if ( right > mid )
__addInterval( p->rchild, left, right, value );
if ( p->lchild->mweight >= p->rchild->mweight )
{
p->mweight = p->lchild->mweight;
p->pos = p->lchild->pos;
}
else {
p->mweight = p->rchild->mweight;
p->pos = p->rchild->pos;
}
}
int hpSegmentTree::__getMaxInInterval( node *p, int left, int right, int *ret )
{
int mid = (p->left+p->right)>>1;
int r = p->r;
if ( left <= p->left && right >= p->right )
{
*ret = p->pos;
return p->mweight;
}
p->lchild->mweight += r;
p->lchild->r += r;
p->rchild->mweight += r;
p->rchild->r += r;
p->r = 0;
if ( left <= mid && right > mid )
{
int l, lp, rp;
l = __getMaxInInterval( p->lchild, (left>p->left)?left:p->left, mid, &lp );
r = __getMaxInInterval( p->rchild, mid+1, (right<p->right)?right:p->right, &rp );
if ( l >= r )
{
*ret = lp;
return l;
}
else {
*ret = rp;
return r;
}
}
else if ( right <= mid )
{
return __getMaxInInterval( p->lchild, (left>p->left)?left:p->left, right, ret );
}
else if ( left > mid )
{
return __getMaxInInterval( p->rchild, left, (right<p->right)?right:p->right, ret );
}
}
void hpSegmentTree::__update( node *p )
{
if ( p->lchild != NULL )
{
p->lchild->mweight = p->mweight;
__update( p->lchild );
}
if ( p->rchild != NULL )
{
p->rchild->mweight = p->mweight;
__update( p->rchild );
}
}
////////////////////////////////////////////////////////////////
int main( int argc, char *argv[] )
{
int n, m, i, a, b, c, pos, result;
char ch;
hpSegmentTree tree;
while ( scanf("%d%d", &n, &m) != EOF && n && m )
{
tree.BuildSegmentTree( 1, n );
result = 0;
for ( i = 0; i < m; ++ i )
{
scanf(" %c%d%d", &ch, &a, &b);
if ( ch == 'I' )
{
scanf("%d", &c);
tree.AddInterval( a, b, c );
}
else {
result = tree.GetMaxInInterval( a, b, &pos );
tree.AddInterval( pos, pos, -result );
printf("%d\n", result );
}
}
tree.Clear();
}
tree.Clear();
return 0;
}
用这段代码过了Sicily 1686,没有加红色代码,就会超时,由此可见它的重要性。