poj 2823 Sliding Window [线段树]

pku 2823 sliding window 线段树解
题意:一组n个数,一个窗口,大小k,找出窗口中的min和max,然后移动窗口,循环操作。网上有部分说可以用双向单调队列来做,个人分析,觉得如果设计特殊数据的话,可能导致时间复杂度是n^2,而使用线段树的时间复杂度是nlog(n),这题是我做的第一个线段树!所以大概的写下解题报告;

每个节点中主要存的主要信息是当前区间的min和max,其实个人感觉线段树主要的是决定好节点中记录的信息!
如果设计了这样的数据结构基本上就可以解决了!

  1 
  2 
  3 
  4 #include<stdio.h>
  5 
  6 int data[1000010] ;
  7 
  8 struct tnode
  9 {
 10     int left , right ;
 11     int min , max ;
 12 } t[1000010*4];
 13 
 14 struct out
 15 {
 16     int min , max ;
 17 }  dataout[1000010] ;
 18 
 19 void create( int st , int ed , int r )
 20 {
 21     t[r].left = st ;
 22     t[r].right = ed ;    
 23     
 24     if( st == ed )
 25     {
 26         t[r].min = t[r].max = data[st] ; 
 27         return ; 
 28     }
 29 
 30     int mid = (st+ed)>>1 ;
 31     create( st , mid , r *2 )  ;
 32     create( mid+1 , ed , r*2+1) ; 
 33 
 34     // min
 35     t[r].min = t[r*2].min ;
 36     if( t[r].min > t[r*2+1].min )
 37         t[r].min = t[r*2+1].min ;
 38     
 39     // max
 40      t[r].max = t[r*2].max ;        
 41     if( t[r].max < t[r*2+1].max  )    
 42         t[r].max = t[r*2+1].max ;
 43 
 44 }
 45 
 46 void search( int st ,int ed , int & min , int & max , int r = 1)
 47 {
 48     if( st == t[r].left && ed == t[r].right )    
 49     {
 50         min = t[r].min ;
 51         max = t[r].max ;
 52         return ;
 53     }        
 54     
 55     int mid = ( t[r].left + t[r].right ) >> 1 ;        
 56     
 57     if( mid >= ed )    
 58     {
 59         search( st , ed , min , max , r * 2 ) ;        
 60     }
 61     else if( mid < st )
 62     {
 63         search( st , ed , min , max , r * 2 +1 ) ; 
 64     }
 65     else
 66     {
 67         int min2 , max2 ;
 68         search( st , mid , min , max , r * 2 ) ;
 69         search( mid+1 , ed , min2 , max2 , r *2 +1  ) ;         
 70         
 71         if( min > min2 )
 72             min = min2 ;
 73         if( max < max2 )    
 74             max = max2 ;
 75 
 76     }    
 77 }
 78 
 79 int main()
 80 {
 81     //freopen( "in.txt" , "r" , stdin ) ;
 82     int n , k ;
 83     int i ;
 84     scanf( "%d%d" , &n , & k ) ;
 85     for( i = 1 ; i<= n ; i++ )
 86         scanf( "%d" , & data[i]);
 87 
 88     create( 1 , n , 1 ) ;
 89     
 90     for( i = 1 ; i <= n -+1 ; i++ )    
 91     {
 92         search( i , i + k -1 , dataout[i].min , dataout[i].max , 1 ) ;
 93     }    
 94     printf( "%d" , dataout[1].min ) ;    
 95     for( i = 2 ; i<= n- k +1 ; i++  )
 96         printf( " %d" , dataout[i].min ) ;    
 97     printf("\n") ;
 98     
 99     printf("%d" , dataout[1].max ) ;    
100     for( i = 2 ; i<= n-+1 ; i++ )
101         printf(" %d" , dataout[i].max ) ;
102     printf("\n") ;
103     return  0 ;
104 }

posted on 2009-11-06 14:36 xunil 阅读(465) 评论(0)  编辑 收藏 引用 所属分类: ACM


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年10月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿

随笔档案

文章分类

文章档案

相册

收藏夹

搜索

最新评论

阅读排行榜

评论排行榜