hdu5316 线段树 by java

区间更新查询优化
本文介绍了一种使用线段树进行区间更新与查询的高效算法实现。该算法适用于处理大规模数据集,通过递归构建和更新线段树节点,能够快速响应区间最大值的查询请求。文章详细展示了输入处理、线段树构建、区间更新及查询的具体实现。
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;



public class Main {

        public static void main(String[] args) throws IOException{
                StreamTokenizer cin = new StreamTokenizer(new BufferedInputStream(System.in)); 
                InputReader in = new InputReader(System.in)  ;
                PrintWriter out = new PrintWriter(System.out) ;

                int t = in.nextInt() ;
                while(t-- > 0){
                         new Task().solve(in, out)  ;  // out.flush() ;
                }

                out.flush() ;

        }

}

class Task{
            static final int  maxn = 100002 ;
            static final long inf =  -1000000000000008L  ;

            static class E{ 
                         long jj , jo , oo , oj ;
                         public E(long _jj , long _jo , long _oj , long _oo){
                                 this.jj = _jj ;
                                 this.jo = _jo ;
                                 this.oj = _oj ;
                                 this.oo = _oo ;
                         }
                        public E() {
                        }
            }

            static E[] elem = new E[maxn<<2] ;

            static long[]  a = new long[maxn]  ;

            E    up(E l , E r){
                      E e  = new E() ;
                      e.jj = Math.max(l.jj , r.jj) ;
                      e.jj = Math.max(e.jj , l.jj + r.oj) ;
                      e.jj = Math.max(e.jj , l.jo + r.jj) ;

                      e.jo = Math.max(l.jo , r.jo) ;
                      e.jo = Math.max(e.jo , l.jj + r.oo) ;
                      e.jo = Math.max(e.jo , l.jo + r.jo) ;

                      e.oj = Math.max(l.oj , r.oj) ;
                      e.oj = Math.max(e.oj , l.oj + r.oj) ;
                      e.oj = Math.max(e.oj , l.oo + r.jj) ;

                      e.oo = Math.max(l.oo , r.oo) ;
                      e.oo = Math.max(e.oo , l.oj + r.oo) ;
                      e.oo = Math.max(e.oo , l.oo + r.jo) ;

                      return e ;
            }

            void  make(int l , int r , int t){
                      if(l == r){
                               if((l & 1) > 0)  elem[t] = new E(a[l] , inf , inf , inf) ;
                               else elem[t] = new E(inf , inf , inf , a[l])  ;
                               return ;
                      }
                      int m = (l + r) >> 1 ;
                      make(l , m , t<<1) ;
                      make(m+1 ,  r , t<<1|1) ;
                      elem[t] = up(elem[t<<1] , elem[t<<1|1] )  ;
            }

            void  update(int i , long d , int l , int r ,  int t){
                     if(l == r){
                                 if((i & 1) > 0)  elem[t].jj = d ;
                                 else  elem[t].oo = d ;
                                 return ;
                      }
                      int m = (l + r) >> 1 ;
                      if(i <= m) update(i , d , l , m , t<<1) ;
                      else  update(i , d , m+1 , r , t<<1|1) ;

                      elem[t] =  up(elem[t<<1] , elem[t<<1|1])  ;
            }

            E    ask(int L , int R , int l , int r , int t){
                  if(L <= l && r <= R)  return elem[t] ;
                  int m = (l + r) >> 1 ;
                  E e = new E(inf , inf , inf , inf) ;
                  if(L <= m)  e = up(e , ask(L , R , l , m , t<<1)) ;
                  if(R > m)    e = up(e , ask(L , R , m+1 , r , t<<1|1)) ;
                  return  e ;
            }



          public void solve(InputReader  in , PrintWriter out) throws IOException{

                      int n  = in.nextInt()  ;
                      int m = in.nextInt()  ;
                      for(int i = 1 ; i <= n ; i++)  a[i] = in.nextLong()  ;
                      make(1 , n , 1)  ;
                      while(m-- > 0){
                                int k = in.nextInt() , l = in.nextInt() , r = in.nextInt()  ;
                                if(k == 0){
                                    E e = ask(l , r , 1 , n , 1) ;
                                    out.println( Math.max(Math.max(e.jj , e.jo) , Math.max(e.oj , e.oo)) ) ;
                                }
                                else  update(l , (long)r , 1 , n , 1) ;
                      } 

          }

}



class InputReader{
            public BufferedReader  reader;
            public StringTokenizer  tokenizer;

            public InputReader(InputStream stream){
                        reader = new BufferedReader(new InputStreamReader(stream), 32768) ;
                        tokenizer = null ;
            }

            public String next(){
                        while(tokenizer == null || ! tokenizer.hasMoreTokens()){
                            try{
                                    tokenizer = new StringTokenizer(reader.readLine());
                            }catch (IOException e) {
                                    throw new RuntimeException(e);
                            }
                        }
                        return tokenizer.nextToken();
            }

            public int nextInt() {
                        return Integer.parseInt(next());
            }

            public long nextLong() {
                        return Long.parseLong(next());
            }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值