1. 程式人生 > >線段樹基礎

線段樹基礎

 線段樹模板:(單點增加+區間查詢(查詢序列最大值))

#include<bits/stdc++.h>
using namespace std;
const int SIZE=100100;
struct SegmentTree
{
    int l,r;
    int dat;
}t[SIZE*4];
int a[SIZE];
void build(int p,int l,int r)
{
    t[p].l=l;
    t[p].r=r;
    if(l==r)
    {
        t[p].dat=a[l];
        return ;
    }
    int mid=(l+r)/2;
    build(p*2,1,mid);
    build(p*2+1,mid+1,r);
    t[p].dat=max(t[p*2].dat,t[p*2+1].dat);
}
void change(int p,int x,int v)
{
    if(t[p].l==t[p].r)
    {
        t[p].dat=v;
        return ;
    }
    int mid=(t[p].l+t[p].r)/2;
    if(x<=mid)change(p*2,x,v);
    else change(p*2+1,x,v);
    t[p].dat=max(t[p*2].dat,t[p*2+1].dat);
}
int ask(int p,int l,int r)
{
    if(l<=t[p].l&&r>=t[p].r)return t[p].dat;
    int mid=(t[p].r+t[p].l)/2;
    int val=-(1<<30);
    if(l<=mid)val=max(val,ask(2*p,l,r));
    if(r>mid)val=max(val,ask(1+2*p,l,r));
    return val;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;++i)cin>>a[i];

    build(1,1,n);


    int x,v;
    cin>>x>>v;
    change(1,x,v);


    int l,r;
    cin>>l>>r;
    cout<<ask(1,l,r)<<endl;

}

區間查詢(最大連續欄位和):

新增內容:


    t[p].sum=t[p*2].sum+t[p*2+1].sum;
    t[p].lmax=max(t[p*2].lmax,t[p*2].sum+t[2*p+1].lmax);
    t[p].rmax=max(t[p*2+1].rmax,t[p*2+1].sum+t[p*2].rmax);
    t[p].dat=max(t[p*2].dat,t[p*2+1].dat,t[p*2].rmax+t[p*2+1].lmax);

AC程式碼:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include<algorithm>
#include <set>
#include <queue>
#include <stack>
#include<vector>
#include<map>
#include<ctime>
#define ll long long
using namespace std;
const int MAX=50001;
struct SegmentTree
{
    int l,r;
    int dat;
    int sum,lmax,rmax;



}t[MAX*4];
int a[MAX];
int max(int x,int y,int z)
{
    if(x>y)
    {
        if(x>z)return x;
        else return z;
    }
    else
    {
        if(y>z)return y;
        else return z;
    }
}
int max(int x,int y)
{
    if(x>y)return x;
    return y;
}
void build(int p,int l,int r)
{
    t[p].l=l;
    t[p].r=r;
    if(l==r)
    {
        t[p].dat=a[l];
        t[p].sum=a[l];
        t[p].lmax=t[p].rmax=a[l];

        return ;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);

    t[p].sum=t[p*2].sum+t[p*2+1].sum;
    t[p].lmax=max(t[p*2].lmax,t[p*2].sum+t[2*p+1].lmax);
    t[p].rmax=max(t[p*2+1].rmax,t[p*2+1].sum+t[p*2].rmax);
    t[p].dat=max(t[p*2].dat,t[p*2+1].dat,t[p*2].rmax+t[p*2+1].lmax);
}
void change(int p,int x,int v)
{
    if(t[p].l==t[p].r)
    {
        t[p].dat=v;
        t[p].sum=v;
        t[p].lmax=t[p].rmax=v;
        return ;
    }
    int mid=(t[p].l+t[p].r)/2;
    if(x<=mid)change(p*2,x,v);
    else change(p*2+1,x,v);
    t[p].sum=t[p*2].sum+t[p*2+1].sum;
    t[p].lmax=max(t[p*2].lmax,t[p*2].sum+t[2*p+1].lmax);
    t[p].rmax=max(t[p*2+1].rmax,t[p*2+1].sum+t[p*2].rmax);
    t[p].dat=max(t[p*2].dat,t[p*2+1].dat,t[p*2].rmax+t[p*2+1].lmax);
}
SegmentTree ask(int p,int l,int r)
{
    if(l<=t[p].l&&r>=t[p].r)return t[p];
    int mid=(t[p].l+t[p].r)/2;

    SegmentTree t1,t2,tt;
    if(l<=mid)t1=ask(p*2,l,r);
    if(r>mid)t2=ask(1+2*p,l,r);
    if(l<=mid&&r>mid)
    {
        tt.sum=t1.sum+t2.sum;
        tt.lmax=max(t1.lmax,t1.sum+t2.lmax);
        tt.rmax=max(t2.rmax,t2.sum+t1.rmax);
        tt.dat=max(t1.dat,t2.dat,t1.rmax+t2.lmax);
    }
    else if(l<=mid&&r<=mid)
    {
        tt.sum=t1.sum;
        tt.lmax=t1.lmax;
        tt.rmax=t1.rmax;
        tt.dat=t1.dat;
    }
    else if(l>mid&&r>mid)
    {
        tt.sum=t2.sum;
        tt.lmax=t2.lmax;
        tt.rmax=t2.rmax;
        tt.dat=t2.dat;
    }
    return tt;
}
int solve(int p,int l,int r)
{
    SegmentTree tt=ask(p,l,r);
    return tt.dat;
}
int main()
{
    int n;
    while(cin>>n)
    {
        for(int i=1;i<=n;++i)cin>>a[i];
        build(1,1,n);


        int t;
        cin>>t;
        while(t--)
        {
            int x,y,z;
            cin>>x>>y>>z;

            if(!x)
            {
                change(1,y,z);
            }
            else
            {
                if(y>z)swap(y,z);
                cout<<solve(1,y,z)<<endl;
            }
        }
    }
    return 0;
}