zoukankan      html  css  js  c++  java
  • 线段树模板

    单点更新,区间求最值


    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define N 222222
    
    using namespace std;
    
    int num[N];
    
    struct Tree
    {
        int l;
        int r;
        int max;
    } tree[N*4];
    
    void push_up(int root)
    {
        tree[root].max=max(tree[root<<1].max,tree[root<<1|1].max);
    }
    
    void build(int root,int l,int r)
    {
        tree[root].l=l;
        tree[root].r=r;
        if(tree[root].l==tree[root].r)
        {
            tree[root].max=num[l];
            return;
        }
        int mid=(l+r)/2;
        build(root<<1,l,mid);
        build(root<<1|1,mid+1,r);
        push_up(root);
    }
    void update(int root,int pos,int val)
    {
        if(tree[root].l==tree[root].r)
        {
            tree[root].max=val;
            return;
        }
        int mid=(tree[root].l+ tree[root].r)/2;
        if(pos<=mid)
            update(root<<1,pos,val);
        else
            update(root<<1|1,pos,val);
        push_up(root);
    }
    int query(int root,int L,int R)
    {
        if(L<=tree[root].l&&R>=tree[root].r)
            return tree[root].max;
        int mid=(tree[root].l+ tree[root].r)/2,ret=0;
        if(L<=mid) ret=max(ret,query(root<<1,L,R));
        if(R>mid) ret=max(ret,query(root<<1|1,L,R));
        return ret;
    }
    


    区间更新,区间求和


    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define N 222222
    
    using namespace std;
    
    int num[N];
    
    struct Tree
    {
        int l;
        int r;
        long long sum;
        long long col;
    } tree[N*4];
    
    void push_up(int rt)
    {
        tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
    }
    
    void push_down(int rt,int m)
    {
        if (tree[rt].col!=0)
        {
            tree[rt<<1].col+=tree[rt].col;
            tree[rt<<1|1].col+=tree[rt].col;
            tree[rt<<1].sum+=(long long)(m-(m/2))*tree[rt].col;
            tree[rt<<1|1].sum+=(long long)(m/2)*tree[rt].col;
            tree[rt].col=0;
        }
    }
    
    void build(int root,int l,int r)
    {
        tree[root].l=l;
        tree[root].r=r;
        tree[root].col=0;
        if(tree[root].l==tree[root].r)
        {
            tree[root].sum=num[l];
            return;
        }
        int mid=(l+r)/2;
        build(root<<1,l,mid);
        build(root<<1|1,mid+1,r);
        push_up(root);
    }
    
    void update(int root,int L,int R,int val)
    {
        if(L<=tree[root].l&&R>=tree[root].r)
        {
            tree[root].col+=val;
            tree[root].sum+=(long long)val*(tree[root].r-tree[root].l+1);
            return;
        }
        push_down(root,tree[root].r-tree[root].l+1);
        int mid=(tree[root].l+tree[root].r)/2;
        if (L<=mid)
            update(root<<1,L,R,val);
        if (R>mid)
            update(root<<1|1,L,R,val);
        push_up(root);
    }
    
    
    long long query(int root,int L,int R)
    {
        if(L<=tree[root].l&&R>=tree[root].r)
            return tree[root].sum;
        push_down(root,tree[root].r-tree[root].l+1);
        int mid=(tree[root].l+ tree[root].r)/2;
        long long ret=0;
        if(L<=mid) ret+=query(root<<1,L,R);
        if(R>mid) ret+=query(root<<1|1,L,R);
        return ret;
    }
    

    成段更新,区间求值

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define N 555555
    
    using namespace std;
    const int OO=1e9;
    int num[N];
    int _min,_max,_sum;
    
    struct Tree
    {
        int l;
        int r;
        int max;
        int min;
        int sum;
        int add;
        int set;
    }big_tree[N*4];
    
    void push_up(int root,Tree tree[])
    {
        tree[root].max=max(tree[root<<1].max,tree[root<<1|1].max);
        tree[root].min=min(tree[root<<1].min,tree[root<<1|1].min);
        tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
    }
    
    void push_down(int root,Tree tree[])
    {
        if (tree[root].set!=-1)
        {
            if (tree[root].l!=tree[root].r)
            {
                //传递懒惰标记
                tree[root<<1].add=tree[root<<1|1].add=0;
                tree[root<<1].set=tree[root<<1|1].set=tree[root].set;
                //最更新大值
                tree[root<<1].max=tree[root<<1|1].max=tree[root].set;
                //更新最小值
                tree[root<<1].min=tree[root<<1|1].min=tree[root].set;
                //更新区间和
                tree[root<<1].sum=(tree[root<<1].r-tree[root<<1].l+1)*tree[root].set;
                tree[root<<1|1].sum=(tree[root<<1|1].r-tree[root<<1|1].l+1)*tree[root].set;
            }
            tree[root].set=-1;
        }
        if (tree[root].add>0)
        {
            if (tree[root].l!=tree[root].r)
            {
                //传递懒惰标记
                tree[root<<1].add+=tree[root].add;
                tree[root<<1|1].add+=tree[root].add;
                //更新最大值
                tree[root<<1].max+=tree[root].add;
                tree[root<<1|1].max+=tree[root].add;
                //更新最小值
                tree[root<<1].min+=tree[root].add;
                tree[root<<1|1].min+=tree[root].add;
                //更新区间和
                tree[root<<1].sum+=(tree[root<<1].r-tree[root<<1].l+1)*tree[root].add;
                tree[root<<1|1].sum+=(tree[root<<1|1].r-tree[root<<1|1].l+1)*tree[root].add;
            }
            tree[root].add=0;
        }
    }
    
    void build(int root,int l,int r,Tree tree[])
    {
        tree[root].l=l;
        tree[root].r=r;
        if(tree[root].l==tree[root].r)
        {
            tree[root].max=0;
            tree[root].min=0;
            tree[root].sum=0;
            tree[root].add=0;
            tree[root].set=-1;
            return;
        }
        int mid=(l+r)/2;
        build(root<<1,l,mid,tree);
        build(root<<1|1,mid+1,r,tree);
        push_up(root,tree);
    }
    
    void update_add(int root,int L,int R,int val,Tree tree[])
    {
    
        if(L<=tree[root].l&&R>=tree[root].r)
        {
            tree[root].add+=val;
            tree[root].max+=val;
            tree[root].min+=val;
            tree[root].sum+=(tree[root].r-tree[root].l+1)*val;
            return;
        }
        push_down(root,tree);
        int mid=(tree[root].l+tree[root].r)/2;
        if(L<=mid)
            update_add(root<<1,L,R,val,tree);
        if (R>mid)
            update_add(root<<1|1,L,R,val,tree);
        push_up(root,tree);
    }
    
    void update_set(int root,int L,int R,int val,Tree tree[])
    {
        if(L<=tree[root].l&&R>=tree[root].r)
        {
            tree[root].set=val;
            tree[root].add=0;
            tree[root].max=val;
            tree[root].min=val;
            tree[root].sum=(tree[root].r-tree[root].l+1)*val;
            return;
        }
        push_down(root,tree);
        int mid=(tree[root].l+tree[root].r)/2;
        if(L<=mid)
            update_set(root<<1,L,R,val,tree);
        if (R>mid)
            update_set(root<<1|1,L,R,val,tree);
        push_up(root,tree);
    }
    
    
    void query(int root,int L,int R,Tree tree[])
    {
        if(L<=tree[root].l&&R>=tree[root].r)
        {
            _min=min(_min,tree[root].min);
            _max=max(_max,tree[root].max);
            _sum+=tree[root].sum;
            return;
        }
        push_down(root,tree);
        int mid=(tree[root].l+tree[root].r)/2;
        if(L<=mid) query(root<<1,L,R,tree);
        if(R>mid) query(root<<1|1,L,R,tree);
    }
    






  • 相关阅读:
    What are the difference between DDL, DML and DCL commands?
    Dingjun123 :使用Partitioned Outer Join实现稠化报表
    Oracle Clusters
    Google实验室能力倾向测试(第一题及解答)
    搜索系统中基于字典的逆向中文分词
    vc++ 深入浅出 窗口创建过程
    计算机网络基础知识1
    线性代数学习之对称矩阵与矩阵的SVD分解
    珍爱生命
    str2hash
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226377.html
Copyright © 2011-2022 走看看