• 线段树区间修改,区间求和,区间求平方和,最大最小值


    【代码】

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<set>
    using namespace std;
    #define f(i,n) for(int i=1;i<=(n);i++)
    #define ll long long
    #define INF 1<<30
    #define N 100010
    int read()
    {
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while( isdigit(c)){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int a[N];
    ll maxn[3*N],sum[3*N],minn[3*N],sumf[3*N],tag[3*N];
    int n,q,z;
    //向上传递 
    void pushup(int o,int l,int r)
    {
        int lo=2*o,ro=2*o+1,m=(l+r)>>1;
        sum[o]=sum[lo]+sum[ro];
        maxn[o]=max(maxn[lo],maxn[ro]);
        minn[o]=min(minn[lo],minn[ro]);
        sumf[o]=sumf[lo]+sumf[ro];
    }
    //定义线段树 
    void dingyi(int o,int l,int r)
    {
        if(l==r)
        {
            sum[o]=maxn[o]=minn[o]=a[l];
            sumf[o]=a[l]*a[l];
            return;
        }
        int lo=2*o,ro=2*o+1,m=(l+r)>>1;
        dingyi(lo,l,m);
        dingyi(ro,m+1,r);
        pushup(o,l,r);
    }
    //向下传递tag 
    void pushdown(int o,int l,int r)
    {
        if(l==r)return;
        int lo=2*o,ro=2*o+1,m=(l+r)>>1;
        if(tag[o])
        {
            tag[lo]+=tag[o];
            tag[ro]+=tag[o];
            sumf[lo]+=(ll)(m-l+1)*tag[o]*tag[o]+(ll)2*tag[o]*sum[lo];
            sumf[ro]+=(ll)(r-m)*tag[o]*tag[o]+(ll)2*tag[o]*sum[ro];
            sum[lo]+=(ll)(m-l+1)*tag[o];
            sum[ro]+=(ll)(r-m)*tag[o];
            maxn[lo]+=tag[o];
            maxn[ro]+=tag[o];
            minn[lo]+=tag[o];
            minn[ro]+=tag[o];
        }
        tag[o]=0;
    }
    //区间加 
    int addl,addr,addi;
    void add(int o,int l,int r)
    {
        if(l>=addl&&r<=addr)
        {
            sumf[o]+=(ll)(r-l+1)*addi*addi+2ll*addi*sum[o];
            sum[o]+=(ll)(r-l+1)*addi;
            maxn[o]+=addi;
            minn[o]+=addi;
            tag[o]+=addi;
            return;
        }
        pushdown(o,l,r);
        int lo=2*o,ro=2*o+1,m=(l+r)>>1;
        if(addl<=m)add(lo,l,m);
        if(addr>m)add(ro,m+1,r);
        pushup(o,l,r);
    }
    //区间查询 
    ll qsum=0,qsumf=0;
    int ql,qr;
    void query(int o,int l,int r)
    {
        if(l>=ql&&r<=qr)
        {
            qsum+=sum[o];
            qsumf+=sumf[o];
            return;
        }
        int lo=2*o,ro=2*o+1,m=(l+r)>>1;
        pushdown(o,l,r);
        if(ql<=m)query(lo,l,m);
        if(qr>m)query(ro,m+1,r);
        pushup(o,l,r);
    }
    int main()
    {
        n=read();
        q=read();
        f(i,n)a[i]=read();
        dingyi(1,1,n);
        f(i,q)
        {
            z=read();
            if(z==1)
            {
                addl=read();
                addr=read();
                scanf("%lld",&addi);
                if(addi==0)continue;
                add(1,1,n);
            }
            if(z==2)
            {
                ql=read();
                qr=read();
                qsum=0;
                qsumf=0;
                query(1,1,n);
            }
        }
    }
    
    
  • 相关阅读:
    js中serialize() 序列化表单时自动url编码
    Oracle账户被锁解决:ora-28000:the account is locked
    jvm(二)------各个运行时数据库常见内存溢出分析与模拟
    解决 maven构建的web项目无法在外部Tomcat中运行的问题
    java源码分析之LinkedList(转)
    ArrayList源码剖析
    详解Swing中JTree组件的功能
    java 制作QQ登录界面
    java 类与类之间的关系 及uml图
    java 限定控制台输入值的类型
  • 原文地址:https://www.cnblogs.com/qwerfcxs/p/7811088.html
Copyright © 2020-2023  润新知