• HDU1166 敌兵布阵 不完全线段树


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

      

      

  • 相关阅读:
    基本数据类型
    概率—基础基本概念
    3.21上午
    3.10下午
    贪心算法回顾
    学习wait、notify和synchronized及Lock
    使用Files更优雅的对文件操作
    Linux下常用命令整理
    Unix下日志操作、访问GET请求
    操作Unix下docker中的redis
  • 原文地址:https://www.cnblogs.com/Lyush/p/2138384.html
Copyright © 2020-2023  润新知