zoukankan      html  css  js  c++  java
  • AT2412 【最大の和】

    这是什么!!

    无修改 线段树 板子啊!!

    看到题解中竟没有一片线段树题解,于是我打算来普及一发装一波

    这道题仅涉及两个线段树最基本操作:

    建树 以及 区间查询

    代码注释很详细,这里就不过多赘述,直接上代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #define maxn 100005
    
    using namespace std;
                        //优雅的空行                   
    int n,k,a[maxn<<2],L[maxn<<2],R[maxn<<2],sum[maxn<<2];
    //L[rt]节点rt的左区间,R[rt]节点rt的右区间,sum[rt]维护区间rt的和 
    
    //一些人习惯写到结构体里,但还是习惯写数组
    
    void build(int rt,int l,int r)//建l~r区间的线段树,当前编号为rt
    {
    
    	L[rt]=l,R[rt]=r;//记录rt区间的左端点与右端点
        
    	if(l==r){//当区间只剩一时个点,进行赋值操作
    		sum[rt]=a[l];//写成sum[rt]=a[r]等效
    		return ;//然后向上回溯
    	}
        
    	int mid=(l+r)>>1;//注意:线段树是一颗二叉树,因此要取中点
        
    	build(rt<<1,l,mid);//递归建造rt的左子树(左儿子),rt<<1 -> rt*2
        
    	build(rt<<1|1,mid+1,r);//递归建造rt的右子树(右儿子),rt<<1|1 -> rt*2+1
        
    	sum[rt]=sum[rt<<1]+sum[rt<<1|1];//向上回溯时更新sum[rt]的值
    }
    
    int query(int rt,int l,int r)//区间查询:查询l~r区间的和
    {
    
        if(L[rt]==l&&R[rt]==r)return sum[rt];//当当前区间与所查询区间重合时,直接返回sum[rt]
        
        int mid=(L[rt]+R[rt])>>1;//同样二分,取中点
        if(r<=mid)//如果要查询的区间完全在左子树,则进入左子树
            return query(rt<<1,l,r);
            
        if(l>mid)//如果要查询的区间完全在右子树,则进入右子树
            return query(rt<<1|1,l,r);
            
        return 
        query(rt<<1,l,mid)+query(rt<<1|1,mid+1,r);//否则返回其在左区间与右区间的和		
    }
    
    int main()
    {
    	cin>>n>>k;
    	for(int i=1;i<=n;i++)cin>>a[i];
    	build(1,1,n);//调用入口 :从节点1开始建造1~n的线段树
    	int maxm=-9999;
    	for(int i=1;i<=n;i++){
    		int j=i+k-1;//保证区间长度为k
    		if(j>n)break;
    		maxm=max(maxm,query(1,i,j));//从节点1开始向下,查询i~j的和,同时用maxm记录答案
    	}
    	cout<<maxm<<'
    ';
    	return 2333;//卖一波萌
    }
    

    有一点不好的事:
    线段树的常数一般很大,有些题会卡这一点

    此题正解应该为前缀和,大概快一个log吧..
    啊哈哈

    为了代码整洁,多加了几个空行..

  • 相关阅读:
    stm32 单片机
    #pragma hdrstop
    #pragma预处理命令
    用define 宏定义注释符号
    ANSI 标准C 还定义了如下几个宏
    国际C 语言乱码大赛(IOCCC )
    深入浅出C语言中的柔性数组
    有符号数与无符号数之间运算问题
    c 语言 register 关键字
    Windows堆思维导图--Windows pro sp3
  • 原文地址:https://www.cnblogs.com/Hydrogen-Helium/p/11738070.html
Copyright © 2011-2022 走看看