zoukankan      html  css  js  c++  java
  • 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;
    			}
    		}
    	}
    } 
    

      

      

  • 相关阅读:
    eyou通用标签的调取
    eyou头部相关标签的调用
    自增标签循环+1的方法
    文章内容页相关的标签
    当前栏目有多少文章
    指定栏目最顶级栏目名称
    当前单页正文
    Python-pandas常用函数
    监控在线平台
    网页爬虫---音乐
  • 原文地址:https://www.cnblogs.com/Lyush/p/2138384.html
Copyright © 2011-2022 走看看