HDU-1166 敌兵布阵 不完全线段树
写的这个伪线段树花了一个下午,为什么说是伪线段树呢,因为这道题目其实并没有对一定域进行更新,而只是找的某个点,所以这里的程序在找的时候无论是要更新的结点还是经过的路径都统一的 " += update " 了,加油,今天晚上在写点题目,写一个完整版的出来。小结也就等到下个完整版再一一写出来。
代码如下:
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> using namespace std; int N; union Mix { int sum; int pos; }; struct Node { int left, right; Mix x; }e[200005], info; void creat( ) { queue< Node >q; e[1].left= 1, e[1].right= N+ 1; info.left= 1, info.right= N+ 1, info.x.pos= 1; q.push( info ); while( !q.empty() ) { Node obj= q.front(); q.pop(); if( obj.right- obj.left== 1 ) { continue; } int lch= obj.x.pos<< 1, rch= ( obj.x.pos<< 1 )+ 1; e[lch].left= obj.left, e[lch].right= ( obj.left+ obj.right )>> 1; if( e[lch].right- e[lch].left> 1 ) { info.left= e[lch].left, info.right= e[lch].right, info.x.pos= lch; q.push( info ); } e[rch].left= e[lch].right, e[rch].right= obj.right; if( e[rch].right- e[rch].left> 1 ) { info.left= e[rch].left, info.right= e[rch].right, info.x.pos= rch; q.push( info ); } } } int getsum( int l, int r ) { int sum= 0; queue< Node >q; info.left= l, info.right= r+ 1, info.x.pos= 1; q.push( info ); while( !q.empty() ) { Node obj= q.front(); q.pop(); if( obj.left== e[obj.x.pos].left&& obj.right== e[obj.x.pos].right ) { sum+= e[obj.x.pos].x.sum; } else { int mid= ( e[obj.x.pos].left+ e[obj.x.pos].right )>> 1; if( obj.left>= mid ) { info.left= obj.left, info.right= obj.right, info.x.pos= ( obj.x.pos<< 1 )+ 1; q.push( info ); } else if( obj.right<= mid ) { info.left= obj.left, info.right= obj.right, info.x.pos= obj.x.pos<< 1; q.push( info ); } else { info.left= obj.left, info.right= mid, info.x.pos= obj.x.pos<< 1; q.push( info ); info.left= mid, info.right= obj.right, info.x.pos= ( obj.x.pos<< 1 )+ 1; q.push( info ); } } } return sum; } void add( int pos, int num ) { bool finish= false; int i= 1; while( !finish ) { if( e[i].left== pos&& e[i].right== pos+ 1 ) { e[i].x.sum+= num; finish= true; break; } e[i].x.sum+= num; if( pos>= ( ( e[i].left+ e[i].right )>> 1 ) ) { i= ( i<< 1 )+ 1; } else { i= i<< 1; } } } int main() { int T; char op[10]; scanf( "%d", &T ); for( int t= 1; t<= T; ++t ) { scanf( "%d", &N ); memset( e, 0, sizeof( e ) ); creat(); for( int i= 1; i<= N; ++i ) { int c; scanf( "%d", &c ); add( i, c ); } printf( "Case %d:\n", t ); while( scanf( "%s", op ), op[0]!= 'E' ) { int pos, num, l, r; switch( op[0] ) { case 'Q': scanf( "%d %d", &l, &r ); printf( "%d\n", getsum( l, r ) ); break; case 'S': scanf( "%d %d", &pos, &num ); add( pos, -num ); break; case 'A': scanf( "%d %d", &pos, &num ); add( pos, num ); break; } } } }