czl蒟蒻的模板库5——线段树

来源:互联网 发布:织梦cms重新安装 编辑:程序博客网 时间:2024/05/21 12:43

求区间和:

#include <bits/stdc++.h>using namespace std;const int maxn=100005;typedef long long ll;struct node{    ll val;    ll addmark;}no[maxn*4];ll a[maxn];void build(int pos,int l,int r){    no[pos].addmark=0;    if(l==r)    {        no[pos].val=a[l];        return ;    }    else     {        int mid=(l+r)/2;        build(pos*2+1,l,mid);        build(pos*2+2,mid+1,r);        no[pos].val=no[pos*2+1].val+no[pos*2+2].val;    }}void push_down(int now,int l,int r){    if(no[now].addmark!=0)    {        // printf("left:%d right:%d\n",now*2+1,now*2+2);        int mid=(l+r)>>1;        no[now*2+1].addmark+=no[now].addmark;        no[now*2+2].addmark+=no[now].addmark;        no[now*2+1].val+=no[now].addmark*(mid-l+1);        no[now*2+2].val+=no[now].addmark*(r-mid);        no[now].addmark=0;    }}ll find(int pos,int nowl,int nowr,int l,int r){    if(nowl>r||nowr<l)    {        return 0;    }    if(nowl>=l&&nowr<=r)    {        return no[pos].val;    }    push_down(pos,nowl,nowr);    int mid=(nowl+nowr)/2;    return find(pos*2+1,nowl,mid,l,r)+find(pos*2+2,mid+1,nowr,l,r);}void change(int pos,int nowl,int nowr,int l,int r,ll addval){    // printf("%d %d\n", nowl,nowr);    if(nowl>r||nowr<l)return;    if (nowl>=l&&nowr<=r)    {        no[pos].addmark+=addval;        no[pos].val+=addval*(nowr-nowl+1);        return ;    }    push_down(pos,nowl,nowr);    int mid=(nowl+nowr)/2;    change(pos*2+1,nowl,mid,l,r,addval);    change(pos*2+2,mid+1,nowr,l,r,addval);    no[pos].val=no[pos*2+1].val+no[pos*2+2].val;}int main(){    int n,m;    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)    {        scanf("%lld",&a[i]);    }    build(0,1,n);    int com;    // for(int i=0;i<2*n-1;i++)    // {    //  printf("%d->%d\n",i,no[i].val);    // }    for(int i=1;i<=m;i++)    {           scanf("%d",&com);        if(com==1)        {            int l,r;            ll add;            scanf("%d%d%lld",&l,&r,&add);            change(0,1,n,l,r,add);        }        else         {            int l,r;            scanf("%d%d",&l,&r);            printf("%lld\n",find(0,1,n,l,r));        }        // puts("now:");        // for(int i=0;i<2*n-1;i++)        // {        //  printf("%d->%d\n",i,no[i].val);        // }        // system("pause");    }    return 0;}

求区间最小值:

#include <bits/stdc++.h>using namespace std;const int maxn=1005;struct node{    int val;    int addmark;}no[maxn];int a[maxn];void build(int pos,int l,int r){    no[pos].addmark=0;    if(l==r)    {        no[pos].val=a[l];        return ;    }    else     {        int mid=(l+r)/2;        build(pos*2+1,l,mid);        build(pos*2+2,mid+1,r);        no[pos].val=min(no[pos*2+1].val,no[pos*2+2].val);    }}void push_down(int now){    if(no[now].addmark!=0)    {        no[now*2+1].addmark+=no[now].addmark;        no[now*2+2].addmark+=no[now].addmark;        no[now*2+1].val+=no[now].addmark;        no[now*2+2].val+=no[now].addmark;        no[now].addmark=0;    }}int find(int pos,int nowl,int nowr,int l,int r){    if(nowl>r||nowr<l)    {        return 0x3f3f3f3f;    }    if(nowl>=l&&nowr<=r)    {        return no[pos].val;    }    push_down(pos);    int mid=(nowl+nowr)/2;    return min(find(pos*2+1,nowl,mid,l,r),find(pos*2+2,mid+1,nowr,l,r));}void change(int pos,int nowl,int nowr,int l,int r,int addval){    if(nowl>r||nowr<l)return;    if (nowl>=l&&nowr<=r)    {        no[pos].addmark+=addval;        no[pos].val+=addval;        return ;    }    push_down(pos);    int mid=(nowl+nowr)/2;    change(pos*2+1,nowl,mid,l,r,addval);    change(pos*2+2,mid+1,nowr,l,r,addval);    no[pos].val=min(no[pos*2+1].val,no[pos*2+2].val);}int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d",&a[i]);    }    build(0,1,n);    change(0,1,n,1,3,5);    int m;    scanf("%d",&m);    for(int i=1;i<=m;i++)    {        int l,r;        scanf("%d%d",&l,&r);        printf("%d\n",find(0,1,n,l,r));    }}