您的位置:首页 > 其它

HDU-1166 敌兵布阵 不完全线段树

2011-08-14 19:53 369 查看
  写的这个伪线段树花了一个下午,为什么说是伪线段树呢,因为这道题目其实并没有对一定域进行更新,而只是找的某个点,所以这里的程序在找的时候无论是要更新的结点还是经过的路径都统一的 " += 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;
}
}
}
}


  

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: