ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【模板】线段树

2022-03-26 13:34:06  阅读:141  来源: 互联网

标签:return val rs int 线段 lmid delta 模板


RT,本人自己写的线段树,支持区修区查和RMQ。

//By lzj
#include <cstdio>
#define ri register int
#define ls p<<1
#define rs p<<1|1
#define int long long
#define INF 1e15 
using namespace std;

const int N=1e6+15;

struct node{
    int l,r;
    int tag1,tag2;
    int sum,maxn,minn;
}tree[N<<2];

inline int read(){
    int f=1; int num=0;
    char ch=getchar();
    while(ch<'0'||ch>'9'){f|=(ch=='-'?-1:1);ch=getchar();}
    while(ch>='0'&&ch<='9'){num=(num<<1)+(num<<3)+(ch^48); ch=getchar();}
    return num*f;
}

void write(int x) {
     if(x<0) putchar('-'),x=-x;
     if(x>9) write(x/10);
     putchar(x%10+'0');
}

int max(int a,int b){
    return a>b?a:b;
}

int min(int a,int b){
	return a<b?a:b;
}

int n,q,op,x,y,z;
int a[N];

void pushup(int p){
	tree[p].sum=tree[ls].sum+tree[rs].sum;
    tree[p].maxn=max(tree[ls].maxn,tree[rs].maxn);
    tree[p].minn=min(tree[ls].minn,tree[rs].minn);
}

void pushdown(int p){
    if(tree[p].tag1!=-INF){
        tree[ls].tag1=tree[rs].tag1=tree[p].tag1;
        tree[ls].maxn=tree[p].tag1;
        tree[rs].maxn=tree[p].tag1;
        tree[ls].minn=tree[p].tag1;
        tree[rs].minn=tree[p].tag1;
        tree[ls].sum=tree[p].tag1*(tree[ls].r-tree[ls].l+1);
        tree[rs].sum=tree[p].tag1*(tree[rs].r-tree[rs].l+1);
        tree[ls].tag2=tree[rs].tag2=0;
        tree[p].tag1=-INF;
    }
    if(tree[p].tag2){
        tree[ls].tag2+=tree[p].tag2;
        tree[rs].tag2+=tree[p].tag2;
        tree[ls].maxn+=tree[p].tag2;
        tree[rs].maxn+=tree[p].tag2;
        tree[ls].minn+=tree[p].tag2;
        tree[rs].minn+=tree[p].tag2;
        tree[ls].sum+=tree[p].tag1*(tree[ls].r-tree[ls].l+1);
        tree[rs].sum+=tree[p].tag1*(tree[rs].r-tree[rs].l+1);
        tree[p].tag2=0;
    }
}

void build(int p,int l,int r){
    tree[p].l=l;tree[p].r=r; tree[p].tag1=-INF;tree[p].tag2=0;
    if(l==r){
        tree[p].sum=tree[p].minn=tree[p].maxn=a[l]; return;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(p);
}

void update1(int p,int l,int r,int delta){
    if(l<=tree[p].l&&tree[p].r<=r){
    	tree[p].sum=delta*(tree[p].r-tree[p].l+1);
        tree[p].maxn=tree[p].minn=delta;
        tree[p].tag1=delta;
        tree[p].tag2=0;
        return;
    }
    pushdown(p);
    int mid=(tree[p].l+tree[p].r)>>1;
    if(l<=mid) update1(ls,l,r,delta);
    if(r>mid) update1(rs,l,r,delta);
    pushup(p);
}

void update2(int p,int l,int r,int delta){
    if(l<=tree[p].l&&tree[p].r<=r){
        tree[p].maxn+=delta;
        tree[p].minn+=delta;
        tree[p].sum+=(tree[p].r-tree[p].l+1)*delta;
        tree[p].tag2+=delta;
        return;
    }
    pushdown(p);
    int mid=(tree[p].l+tree[p].r)>>1;
    if(l<=mid) update2(ls,l,r,delta);
    if(r>mid) update2(rs,l,r,delta);
    pushup(p);
}

int qmax(int p,int l,int r){
    if(l<=tree[p].l&&tree[p].r<=r){
        return tree[p].maxn;
    }
    pushdown(p);
    int mid=(tree[p].l+tree[p].r)>>1,val=-INF;
    if(l<=mid) val=max(val,qmax(ls,l,r));
    if(r>mid) val=max(val,qmax(rs,l,r));
    return val;
}

int qmin(int p,int l,int r){
    if(l<=tree[p].l&&tree[p].r<=r){
        return tree[p].minn;
    }
    pushdown(p);
    int mid=(tree[p].l+tree[p].r)>>1,val=INF;
    if(l<=mid) val=min(val,qmin(ls,l,r));
    if(r>mid) val=min(val,qmin(rs,l,r));
    return val;
}

int query(int p,int l,int r){
    if(l<=tree[p].l&&tree[p].r<=r){
        return tree[p].sum;
    }
    pushdown(p);
    int mid=(tree[p].l+tree[p].r)>>1,val=0;
    if(l<=mid) val+=query(ls,l,r);
    if(r>mid) val+=query(rs,l,r);
    return val;
}

signed main(){
    n=read(); q=read();
    for(ri i=1;i<=n;i++) a[i]=read();
    build(1,1,n);
    while(q--){
        op=read();
        if(op==1){
            x=read(); y=read(); z=read();
            update1(1,x,y,z);
        }
        if(op==2){
            x=read(); y=read(); z=read();
            update2(1,x,y,z);
        }
        if(op==3){
            x=read(); y=read();
            write(qmax(1,x,y));
            putchar('\n');
        }
        if(op==4){
            x=read(); y=read();
            write(qmin(1,x,y));
            putchar('\n');
        }
        if(op==5){
        	x=read(); y=read();
        	write(query(1,x,y));
        	putchar('\n');
        }
    }
    return 0;
}

  

标签:return,val,rs,int,线段,lmid,delta,模板
来源: https://www.cnblogs.com/LByte/p/16058522.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有