• 线段树模板


    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define maxn 100010
    long long sum[maxn<<2],add[maxn<<2];
    void pushup(int rt) {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void pushdown(int rt ,int l,int r) {
        if (add[rt]) {
            add[rt<<1]+=add[rt];
            add[rt<<1|1]+=add[rt];
            sum[rt<<1]+=add[rt]*((l+r)/2-l+1);
            sum[rt<<1|1]+=add[rt]*(r-((l+r)/2+1)+1);
            add[rt]=0;
        }
    }
    void build(int l,int r ,int rt) {
        if (l==r) {
            scanf("%lld",&sum[rt]);
            return ;
        }
        int m=(l+r)>>1;
        build(l,m,rt<<1);
        build(m+1,r,rt<<1|1);
        pushup(rt);
    }
    void updata(int x,int y,int z,int l,int r,int rt) {
        if (x<=l && r<=y ) {
            add[rt]+=z;
            sum[rt]+=z*(r-l+1);
            return ;
        }
        pushdown(rt,l,r);
        int m=(l+r)>>1;
        if (x<=m) updata(x,y,z,l,m,rt<<1);
        if (y>m ) updata(x,y,z,m+1,r,rt<<1|1);
        pushup(rt);
    }
    long long query(int x,int y,int l,int r, int rt) {
        long long ans=0;
        if (x<=l && r<=y) return sum[rt];
        pushdown(rt,l,r);
        int m=(l+r)>>1;
        if (x<=m) ans+=query(x,y,l,m,rt<<1);
        if (y>m ) ans+=query(x,y,m+1,r,rt<<1|1);
        return ans;
    }
    int main() {
        int n,q,t;
        scanf("%d",&t);
        while(t--) {
            scanf("%d",&n);
            memset(add,0,sizeof(add));
            build(1,n,1);
            scanf("%d",&q);
            int x,y,z,a;
            while(q--) {
                scanf("%d",&a);
                if (a) {
                    scanf("%d%d",&x,&y);
                    printf("%.2lf
    ",((double)query(x,y,1,n,1)/(y-x+1)));
                } else {
                    scanf("%d%d%d",&x,&y,&z);
                    updata(x,y,z,1,n,1);
                }
            }
        }
        return 0;
    }
    //更新
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<math.h>
    using namespace std;
    #define maxn 100010
    long long sum[4*maxn],add[4*maxn],a[maxn];
    void pushup(int rt)
    {
        sum[rt]=sum[2*rt]+sum[2*rt+1];
    }
    void pushdown1(int rt,int l,int r)
    {
        if(add[rt])
        {
            int mid=(l+r)/2;
            add[2*rt]+=add[rt];
            add[2*rt+1]+=add[rt];
            sum[2*rt]+=(mid-l+1)*add[rt];
            sum[2*rt+1]+=(r-(mid+1)+1)*add[rt];
            add[rt]=0;
        }
    }
    void pushdown2(int rt,int l,int r)
    {
        if(add[rt])
        {
            int mid=(l+r)/2;
            add[2*rt]=add[rt];
            add[2*rt+1]=add[rt];
            sum[2*rt]=(mid-l+1)*add[rt];
            sum[2*rt+1]=(r-(mid+1)+1)*add[rt];
            add[rt]=0;
        }
    }
    void build(int l,int r,int rt)
    {
        if(l==r);
            sum[rt]=a[r];
        else
        {
            int mid=(l+r)/2;
            build(1,mid,2*rt);
            build(mid+1,r,2*rt+1);
            pushup(rt);
        }
    }
    void updata1(int x,int y,int z,int l,int r,int rt)//区间更新 x到y区间每个数加z
    {
        if(x<=l&&r<=y)
        {
            add[rt]+=z;
            sum[rt]+=z*(r-l+1);
        }
        else
        {
            pushdown(rt,l,r);
            int mid=(l+r)/2;
            if(x<=mid) updata(x,y,z,l,mid,2*rt);
            if(y>=mid+1) updata(x,y,z,mid+1,r,2*rt+1);
            pushup(rt);
        }
    }
    void updata2(int x,int y,int z,int l,int r,int rt)//区间更新,x到y区间的每个数替换成z
    {
        if(x<=l&&r<=y)
        {
            add[rt]=z;
            sum[rt]=z*(r-l+1);
        }
        else
        {
            pushdown2(rt,l,r);
            int mid=(l+r)/2;
            if(x<=mid) updata(x,y,z,l,mid,2*rt);
            if(y>=mid+1) updata(x,y,z,mid+1,r,2*rt+1);
            pushup(rt);
    
        }
    }
    void updatanode(int x,int z,int l,int r,int rt)//单点更新 x位置的数加z
    {
        updata(x,x,z,l,r,rt);
    }
    long long query(int x,int y,int l,int r,int rt)
    {
        if(x<=l&&r<=y)  return sum[rt];
        else
        {
            long long ans=0;
            pushdown(rt);
            int mid=(l+r)/2;
            if(x<=mid) ans+=query(x,y,z,l,mid,2*rt);
            if(y>=mid+1) ans+=query(x,y,z,mid+1,r,2*rt+1);
            return ans;
        }
    }

    区间加 区间求和

    最近学了下lazy标记永久化,于是又重新写了下这题。

    lazy标记永久化,顾名思义就是lazy标记不下放即没有了pushdown,但是为了获得儿子节点的值需要把lazy[rt]的值放到query函数的参数里,往儿子节点方向搜索时带下去。另外update函数的话也是有较之前有变化,体现在现在更新rt节点的值不是把左右子树都更新完了后pushup了,这样会出错,因为儿子节点的sum可能还是以为的值,那么一pushup就错了,解决办法就是每次更新到一个点,马上求出交集对rt点的sum更新。差别大概就是这些了。

    /*
    #include<bits/stdc++.h>
    using namespace std;
    #define ls rt<<1
    #define rs (rt<<1)+1
    #define PI acos(-1)
    #define eps 1e-8
    #define ll long long
    #define fuck(x) cout<<#x<<"     "<<x<<endl;
    typedef pair<int,int> pii;
    const int inf=2e9;
    const int maxn=1e6+10;
    int d[4][2]={1,0,-1,0,0,1,0,-1};
    //int lowbit(int x){return x&-x;}
    //void add(int x,int v){while(x<=n)bit[x]+=v,x+=lowbit(x);}
    //int sum(int x){int ans=0;while(x>=1) ans+=bit[x],x-=lowbit(x);return ans;}
    inline ll read() {
        ll s = 0,w = 1;
        char ch = getchar();
        while(!isdigit(ch)) {
            if(ch == '-') w = -1;
            ch = getchar();
        }
        while(isdigit(ch))
            s = s * 10 + ch - '0',ch = getchar();
        return s * w;
    }
    inline void write(ll x) {
        if(x < 0)
            putchar('-'), x = -x;
        if(x > 9)
            write(x / 10);
        putchar(x % 10 + '0');
    }
    int gcd(int x,int y){
        return y==0?x:gcd(y,x%y);
    }
    
    int n,m,k,a[maxn],b[maxn],f[maxn];
    ll dp[100005];
    
    int main(){
        n=read();
        m=read();
        k=read();
        for(int i=0;i<=k;i++) f[i]=read();
        for(int i=1;i<=m;i++)
            a[i]=read(),b[i]=read();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                for(int k=a[j];k<=1000+a[j];k++)
                    
            }
        }
        return 0;
    }*/
    #include<bits/stdc++.h>
    using namespace std;
    #define ls rt<<1
    #define rs (rt<<1)+1
    #define PI acos(-1)
    #define eps 1e-8
    #define ll long long
    #define fuck(x) cout<<#x<<"     "<<x<<endl;
    typedef pair<int,int> pii;
    const int inf=2e9;
    const int maxn=1e5+10;
    int d[4][2]={1,0,-1,0,0,1,0,-1};
    //int lowbit(int x){return x&-x;}
    //void add(int x,int v){while(x<=n)bit[x]+=v,x+=lowbit(x);}
    //int sum(int x){int ans=0;while(x>=1) ans+=bit[x],x-=lowbit(x);return ans;}
    inline ll read() {
        ll s = 0,w = 1;
        char ch = getchar();
        while(!isdigit(ch)) {
            if(ch == '-') w = -1;
            ch = getchar();
        }
        while(isdigit(ch))
            s = s * 10 + ch - '0',ch = getchar();
        return s * w;
    }
    inline void write(ll x) {
        if(x < 0)
            putchar('-'), x = -x;
        if(x > 9)
            write(x / 10);
        putchar(x % 10 + '0');
    }
    int gcd(int x,int y){
        return y==0?x:gcd(y,x%y);
    }
    
    ll a[maxn],sum[maxn<<2],lazy[maxn<<2];
    
    void build(int rt,int L,int R){
        lazy[rt]=0;
        if(L==R)
        {
            sum[rt]=a[L];
            return ;
        }
        int mid=(L+R)>>1;
        build(ls,L,mid);
        build(rs,mid+1,R);
        sum[rt]=sum[ls]+sum[rs];
    }
    
    void update(int rt,int L,int R,int l,int r,ll v){
        sum[rt]+=v*(min(r,R)-max(l,L)+1);
        if(l<=L&&r>=R){
            lazy[rt]+=v;
            return ;
        }
        int mid=(L+R)>>1;
        if(r<=mid)
            update(ls,L,mid,l,r,v);
        else
            if(l>mid)
                update(rs,mid+1,R,l,r,v);
             else{
                update(ls,L,mid,l,r,v);
                update(rs,mid+1,R,l,r,v);
             }
    }
    
    ll query(int rt,int L,int R,int l,int r,ll tag){
        if(l<=L&&r>=R){
            return sum[rt]+tag*(R-L+1);
        }
        int mid=(L+R)>>1;
        ll sum=0;
        if(r<=mid)
            sum=query(ls,L,mid,l,r,tag+lazy[rt]);
        else
            if(l>mid)
                sum=query(rs,mid+1,R,l,r,tag+lazy[rt]);
             else{
                    sum=query(ls,L,mid,l,r,tag+lazy[rt]);
                    sum+=query(rs,mid+1,R,l,r,tag+lazy[rt]);
                 }
        return sum;
    }
    int main(){
        int n,m;
        n=read();m=read();
        for(int i=1;i<=n;i++) a[i]=read();
        build(1,1,n);
        while(m--){
            int op,x,y,z;
            op=read();
            if(op==1) {
                x=read();y=read();z=read();
                update(1, 1, n,x,y,z);
            } else{
                x=read();y=read();
                printf("%lld
    ",query(1,1,n,x,y,0));
            }
        }
        return 0;
    }
  • 相关阅读:
    JDBC的一些代码
    mysql
    【转载】如何简单地理解Python中的if __name__ == '__main__'
    【转载】用Scikit-Learn构建K-近邻算法,分类MNIST数据集
    数据科学入门---可视化数据
    Sum It Up
    Blue Jeans
    Zball in Tina Town
    Island Transport
    CD
  • 原文地址:https://www.cnblogs.com/eason9906/p/11755143.html
Copyright © 2020-2023  润新知