POJ3468(区间更新线段树)

本文详细介绍了线段树的实现方法,包括如何正确使用scanf和printf进行long long类型数据的输入输出,以及如何利用懒惰标记进行区间更新与查询,避免重复计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 因为long long类型数据输入的错误搞了大半天,所以采用scanf和printf输入输出一定严格遵守格式控制。

先推荐一下大佬的博客链接:https://blog.youkuaiyun.com/dt2131/article/details/58689903

先说一下自己的错误吧~:输出的时候要严格按照格式,输入的时候也相同,比如,在这道题目的程序中scanf("%lld",&tree[rt])

是正确的,但是我一开始的错误输入scanf("%d",&tree[rt])在处理负数的时候会出现错误的输出,因此使用标准输入输出一定要严格遵守格式限制的规定,占位符非常重要!!!

当然,除此之外还要注意:返回的函数值一定要符合函数值的返回类型,否则也会出错。

下面是题目的AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100005;
char str[5];
long long add[maxn<<2];//增加下推标记
long long tree[maxn<<2];
int L,R,C;
int n,m;
void pushup(int rt)
{
    tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    //printf("%d数字已经更新\n",tree[rt]);
    return ;
}
void pushdown(int ln,int rn,int rt)
{//ln,rn分别是左子树和右子树的数字数量
    if(add[rt])
    {//首先将标记下推
        add[rt<<1]+=add[rt];
        add[rt<<1|1]+=add[rt];
     //其次将左子树和右子树的结点向下更新
        tree[rt<<1]+=add[rt]*ln;
        tree[rt<<1|1]+=add[rt]*rn;
        add[rt]=0;
    }
}
void build_tree(int l,int r,int rt)
{
    if(l==r)
    {
        scanf("%lld",&tree[rt]);
        //printf("%d数字已经录入\n",tree[rt]);//检验
        return;
    }
    int m=(l+r)>>1;
    build_tree(l,m,rt<<1);
    build_tree(m+1,r,rt<<1|1);
    pushup(rt);
}
void update(int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        tree[rt]+=(r-l+1)*C;
        add[rt]+=C;//增加懒惰标记,表示本区间的tree值
        //正确,不再下推,子区间的值使用的时候再进行修改
        return;
    }
    int m=(l+r)>>1;
    pushdown(m-l+1,r-m,rt);
    if(L<=m)
        update(l,m,rt<<1);
    if(m<R)
        update(m+1,r,rt<<1|1);
    pushup(rt);
}
long long int query(int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
       ///printf("%d已经被查询到\n",tree[rt]);
       return tree[rt];
    }
    int m=(l+r)>>1;
    pushdown(m-l+1,r-m,rt);
    long long ans=0;
    if(L<=m)
        ans+=query(l,m,rt<<1);
    if(m<R)
        ans+=query(m+1,r,rt<<1|1);
        ///printf("返回的查询值为%d\n",ans);
    return ans;
}
int main()
{
    memset(add,0,sizeof(add));
    memset(tree,0,sizeof(tree));
    scanf("%d%d",&n,&m);
    build_tree(1,n,1);
    for(int i=0;i<m;++i)
    {
        scanf("%s",str);
        if(str[0]=='Q')
        {//区间查询
            scanf("%d%d",&L,&R);
            printf("%lld\n",query(1,n,1));
        }
        else if(str[0]=='C')
        {//区间修改
            scanf("%d%d%d",&L,&R,&C);
            update(1,n,1);
        }
    }
    return 0;
}

新的知识点需要理解的是线段树的下推函数和懒惰标记的使用。

懒惰标记的作用有两个,一个是记录遍历到的位置,另一个是记录下推时要更新多大的值。

通过代码可以看出:在下一次进行区间更新或者区间查询的时候,在当前区间没有落到目标区间时,我们总要首先对当前区间进行下推操作,目的是更新子区间的值,使子区间的值保持正确后,再进行下面的利用。而一旦将懒惰标记使用后(下推操作完成,改变左子树数值和右子树数值,并且将懒惰标记的位置转移到左子树和右子树上后),懒惰标记的两个作用:遍历到的位置下移了,因此不能再使用这个懒惰标记记录当前位置作为遍历到的位置了,记录更新多大的值也转移到左子树和右子树的懒惰标记上了,因此这个懒惰标记失去了它的作用和存在的意义,于是需要add[rt]=0操作。

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值