diff --git a/HDOJ/1556.cpp b/HDOJ/1556.cpp new file mode 100644 index 0000000..9ac48cd --- /dev/null +++ b/HDOJ/1556.cpp @@ -0,0 +1,132 @@ +/// General includes +#include +#include +#include + +#include +using namespace std; +/// 延迟更新: 区间运算更新(加法), 区间运算(求和) +namespace LazySegmentTree +{ + +const int MAXN = 100100; +const int MAXTREENODE = MAXN << 2; + +struct node +{ + int lt,rt; + int val; + int add; +}; + +node tree[MAXTREENODE]; + +void _internal_PushUp(int _indexer) +{ + tree[_indexer].val=tree[_indexer<<1].val+tree[_indexer<<1|1].val; +} +void _internal_PushDown(int _indexer) +{ + if(tree[_indexer].add!=0) + { + /// Broadcast this add value to Left and Right sub-tree node. + tree[_indexer<<1].add+=tree[_indexer].add; + tree[_indexer<<1|1].add+=tree[_indexer].add; + /// Confirm this change by calculate and add changes to sub-trees. + tree[_indexer<<1].val+=tree[_indexer].add * (tree[_indexer<<1].rt-tree[_indexer<<1].lt+1); + tree[_indexer<<1|1].val+=tree[_indexer].add *(tree[_indexer<<1|1].rt-tree[_indexer<<1|1].lt+1); + /// Now Clear this node's add value. + tree[_indexer].add=0; + } +} + +void build(int L,int R,int _indexer=1) +{ + tree[_indexer].lt=L; + tree[_indexer].rt=R; + tree[_indexer].add=0;/// This must be set to 0. + if(L==R) + { + //scanf("%d",&tree[_indexer].val); + tree[_indexer].val = 0; + return; + } + int mid=(L+R)>>1; + build(L,mid,_indexer<<1); + build(mid+1,R,_indexer<<1|1); + /// Update this val from down to up. (>.<) + _internal_PushUp(_indexer); +} + +void update(int L,int R,int ValToAdd,int _indexer=1) +{ + /// Return when L or R exceeds range. So smart ! + if(Rtree[_indexer].rt) return; + if(L<=tree[_indexer].lt&&R>=tree[_indexer].rt) + { + /// This range is covered. So just add the 'add' value, which is called "LAZY" + tree[_indexer].add+=ValToAdd; + tree[_indexer].val+=ValToAdd*(tree[_indexer].rt-tree[_indexer].lt+1); + return; + } + _internal_PushDown(_indexer); + /// This ... Hum.. Seems not so clever... + update(L,R,ValToAdd,_indexer<<1); + update(L,R,ValToAdd,_indexer<<1|1); + _internal_PushUp(_indexer); +} + +int ans; +void basic_query(int L,int R,int _indexer=1) +{ + /// Data to find is not in this range. + if(Rtree[_indexer].rt) return; + /// Data to find is right in this range , or covers this range. + if(L<=tree[_indexer].lt&&R>=tree[_indexer].rt) + { + ans+=tree[_indexer].val; + return ; + } + _internal_PushDown(_indexer); + int mid=(tree[_indexer].lt+tree[_indexer].rt)>>1; + if(R<=mid) + basic_query(L,R,_indexer<<1); + else if(L>mid) + basic_query(L,R,_indexer<<1|1); + else + { + basic_query(L,mid,_indexer<<1); + basic_query(mid+1,R,_indexer<<1|1); + } +} +int query(int L,int R) +{ + ans=0; + basic_query(L,R); + return ans; +} + +}/// End of namespace LazySegmentTree + + +int main() +{ + int n; + while(scanf("%d",&n)==1&&n!=0) + { + LazySegmentTree::build(1,n); + int x,y; + for(int i=0;i