码迷,mamicode.com
首页 > 其他好文 > 详细

线段树

时间:2020-01-01 09:31:57      阅读:60      评论:0      收藏:0      [点我收藏+]

标签:--   ==   pre   连续   struct   const   oid   while   getc   

板子:单点修改+区间查询

#include<bits/stdc++.h>
using namespace std;
struct Tree
{
    int l,r;
    int dat;
    #define l(x) tree[x].l;
    #define r(x) tree[x].r;
    #define d(x) tree[x].dat;
}tree[N*4];
void build(int p,int l,int r)
{
    l(p)=l,r(p)=r;
    if(l==r) {d(p)=a[p];return;}
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1+1,mid+1,r);
    d(p)=max(d(p<<1),d(p<<1+1));
}
void change(int p,int x,int v)
{
    if(l(p)==r(p)) {d(p)=v;return;}
    int mid=(l(p)+r(p))>>1;
    if(x<=mid) change(p<<1,x,v);
    else       change(p<<1+1,x,v);
    d(p)=max(d(p<<1),d(p<<1+1));
}
int ask(int p,int l,int r)
{
    if(l<=l(p)&&r>=r(p)) return d(p);
    int mid=(l(p)+r(p))>>1;
    int val=-(1<<30);
    if(mid>=l) val=max(val,ask(p<<1,l,r));
    if(mid+1<=r) val=max(val,ask(p<<1+1,l,r));
    return val;
}
int main()
{
    build(1,1,n);
    change(1,x,v);
    ask(1,1,n);
} 

T1:求最大连续子段和(单点修改)

//第一次认真的打线段树的板子....
//第一次拼命wrong的点竟然在建树是的赋值,醉了醉了... 
#include<bits/stdc++.h>
using namespace std;
const int N=500010;
int n,T,c[N];
struct Tree
{
    int sum,dat,lmax,rmax,l,r;
    #define l(x) t[x].l
    #define r(x) t[x].r
    #define s(x) t[x].sum
    #define d(x) t[x].dat
    #define lm(x) t[x].lmax
    #define rm(x) t[x].rmax
}t[N*4];
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch==-) ff=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*ff;
}
inline void push(int p)
{
    s(p)=s(p<<1)+s((p<<1)+1);
    lm(p)=max(lm(p<<1),s(p<<1)+lm((p<<1)+1));
    rm(p)=max(rm((p<<1)+1),s((p<<1)+1)+rm(p<<1));
    d(p)=max(max(d(p<<1),d((p<<1)+1)),rm(p<<1)+lm((p<<1)+1));
}
inline void build(int p,int l,int r)
{
    l(p)=l,r(p)=r;
    if(l==r) {s(p)=d(p)=lm(p)=rm(p)=c[l(p)];return;}
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build((p<<1)+1,mid+1,r);
    push(p);
}
inline void change(int p,int x,int v)
{
    if(l(p)==r(p)) {s(p)=d(p)=lm(p)=rm(p)=v;return;}
    int mid=(l(p)+r(p))>>1;
    if(x<=mid) change(p<<1,x,v);
    else       change((p<<1)+1,x,v);
    push(p);
}
inline Tree ask(int p,int l,int r)
{
    if(l<=l(p)&&r>=r(p)) return t[p];
    int mid=(l(p)+r(p))>>1;
    if(r<=mid) return ask(p<<1,l,r);
    else if(l>=mid+1) return ask((p<<1)+1,l,r);
    else 
    {
        Tree a,b,c;
        a=ask(p<<1,l,r);
        b=ask((p<<1)+1,l,r);
        c.sum=a.sum+b.sum;
        c.lmax=max(a.lmax,a.sum+b.lmax);
        c.rmax=max(b.rmax,b.sum+a.rmax);
        c.dat=max(max(a.dat,b.dat),a.rmax+b.lmax);
        return c;
    }
}
int main()
{
    freopen("1.in","r",stdin);
    n=read();T=read();
    for(register int i=1;i<=n;++i) c[i]=read();
    build(1,1,n);
    while(T--)
    {
        int op=read(),x=read(),y=read();
        if(op==1) 
        {
            if(x>y) swap(x,y);
            printf("%d\n",ask(1,x,y).dat);
        }
        else if(op==2) change(1,x,y);
    } 
    return 0;

板子:区间修改+区间查询.

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100010;
int n,m,a[N];
struct Tree
{
    int l,r;
    ll sum,add;
    #define l(x) t[x].l
    #define r(x) t[x].r
    #define sum(x) t[x].sum
    #define add(x) t[x].add
}t[N*4];
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch==-) ff=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*ff;
}
inline void push(int p)
{
    if(add(p))
    {
        sum(p<<1)+=(r(p<<1)-l(p<<1)+1)*add(p);
        sum((p<<1)+1)+=(r((p<<1)+1)-l((p<<1)+1)+1)*add(p);
        add(p<<1)+=add(p);
        add((p<<1)+1)+=add(p);
        add(p)=0;
    }
}
inline void build(int p,int l,int r)
{
    l(p)=l,r(p)=r;
    if(l==r) {sum(p)=a[l];return;}
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build((p<<1)+1,mid+1,r);
    sum(p)=sum(p<<1)+sum((p<<1)+1);
} 
inline void change(int p,int l,int r,ll d)
{
    if(l<=l(p)&&r>=r(p)) 
    {
        sum(p)+=d*(r(p)-l(p)+1);
        add(p)+=d;
        return; 
    }
    push(p);
    int mid=(l(p)+r(p))>>1;
    if(mid>=l) change(p<<1,l,r,d);
    if(mid+1<=r) change((p<<1)+1,l,r,d);
    sum(p)=sum(p<<1)+sum((p<<1)+1); 
}
inline ll ask(int p,int l,int r)
{
    if(l<=l(p)&&r>=r(p)) return sum(p);
    ll val=0;
    push(p);
    int mid=(l(p)+r(p))>>1;
    if(mid>=l) val+=ask(p<<1,l,r);
    if(mid+1<=r) val+=ask((p<<1)+1,l,r);
    return val;
} 
int main()
{
    freopen("1.in","r",stdin);
    n=read();m=read();
    for(register int i=1;i<=n;++i) a[i]=read();
    build(1,1,n); 
    while(m--)
    {
        int op=read();
        if(op==1)
        {
            int x=read(),y=read(),k=read();
            change(1,x,y,k);
        }
        else 
        {
            int x=read(),y=read();
            printf("%lld\n",ask(1,x,y));
        }
    }
    return 0;
} 

线段树

标签:--   ==   pre   连续   struct   const   oid   while   getc   

原文地址:https://www.cnblogs.com/gcfer/p/12128182.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!