记一个 segtree 类的实现 (暂不支持lazy标记)

namespace simpler{
    template<class T,class Sequence=std::vector<T>,class Updater=std::plus<T>>
    class segtree{
    protected:
        size_t siz_n,siz_m;
        Sequence seq;
        Updater upd;
    public:
        segtree():segtree(Sequence(0)){}
        explicit segtree(int n):segtree(Sequence(n,T())){}
        explicit segtree(const Sequence& a){
            if(a.empty()){siz_n=siz_m=0;seq.clear();return ;}
            siz_n=a.size();
            for(siz_m=1;siz_m<siz_n;siz_m<<=1);
            seq=Sequence(siz_m<<1,0);
            for(int i=0;i<siz_n;++i)seq[siz_m+i]=a[i];
            for(int i=siz_m-1;i;--i)seq[i]=upd(seq[i<<1],seq[i<<1|1]);
        }
        inline auto& rebuild(int n=0){return *this=segtree(Sequence(n,T()));}
        inline auto& rebuild(const Sequence& a){return *this=segtree(a);}
        inline bool   empty(){return siz_n?0:1;}
        inline size_t size(){return siz_n;}
        inline size_t max_size(){return siz_m;}
        inline size_t all_size(){return siz_m<<1;}
        inline T at(size_t x){return seq[siz_m+x];}
        inline T top(){return seq[1];}
        void clear(){
            for(int i=1;i<(siz_m<<1);++i)seq[i]=T();
        }
        void set(size_t x,T val){
            seq[siz_m+x]=val;
            for(int i=siz_m+x>>1;i;i>>=1)seq[i]=upd(seq[i<<1],seq[i<<1|1]);
        }
        void update(size_t x,T val){set(x,upd(seq[siz_m+x],val));}
        T query(int l,int r){
            T res=upd(seq[l+siz_m],seq[r+siz_m]);
            for(l+=siz_m,r+=siz_m;l^r^1;l>>=1,r>>=1){
                if(~l&1)res=upd(res,seq[l^1]);
                if( r&1)res=upd(res,seq[r^1]);
            }
            return res;
        }
    };
}

示例([BalticOI 2015]Hacker

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
namespace simpler{
#define SIMPLER_GETCHAR_IS_NUMBER(ch) ((ch)>='0'&&(ch)<='9')
    template<class T=unsigned>
    T readu(void){//read an unsigned integer
        T x(0);static char ch=getchar();
        for(;!SIMPLER_GETCHAR_IS_NUMBER(ch);ch=getchar());
        for(; SIMPLER_GETCHAR_IS_NUMBER(ch);ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
        return x; 
    }
#undef  SIMPLER_GECHAR_IS_NUMBER
    template<class T>inline T& readu(T& x){return x=readu<T>();}
    template<class T,class ...Args>auto& readu(T& x,Args& ...args){return x=readu<T>(),readu(args...);}//read unsigned integers

    template<class T>inline T  smax(T  x){return x;}
    template<class T>inline T  smin(T  x){return x;}
    template<class T>inline T& umax(T& x){return x;}
    template<class T>inline T& umin(T& x){return x;}
    template<class T,class ...Args>T  smax(T  x,Args ...args){return max(x,(T)smax(args...));}//get the greatest element of a sequence
    template<class T,class ...Args>T  smin(T  x,Args ...args){return min(x,(T)smin(args...));}//get the least    element of a sequence
    template<class T,class ...Args>T& umax(T& x,Args ...args){return x=smax(x,args...);}//keep the first element being the greatest
    template<class T,class ...Args>T& umin(T& x,Args ...args){return x=smin(x,args...);}//keep the first element being the least

    
    template<class T,class Sequence=std::vector<T>,class Updater=std::greater<T>>
    class segtree{
    protected:
        size_t siz_n,siz_m;
        Sequence seq;
        Updater upd;
    public:
        segtree():segtree(Sequence(0)){}
        explicit segtree(int n):segtree(Sequence(n,T())){}
        explicit segtree(const Sequence& a){
            if(a.empty()){siz_n=siz_m=0;seq.clear();return ;}
            siz_n=a.size();
            for(siz_m=1;siz_m<siz_n;siz_m<<=1);
            seq=Sequence(siz_m<<1,0);
            for(int i=0;i<siz_n;++i)seq[siz_m+i]=a[i];
            for(int i=siz_m-1;i;--i)seq[i]=upd(seq[i<<1],seq[i<<1|1]);
        }
        inline auto& rebuild(int n=0){return *this=segtree(Sequence(n,T()));}
        inline auto& rebuild(const Sequence& a){return *this=segtree(a);}
        inline bool   empty(){return siz_n?0:1;}
        inline size_t size(){return siz_n;}
        inline size_t max_size(){return siz_m;}
        inline size_t all_size(){return siz_m<<1;}
        inline T at(size_t x){return seq[siz_m+x];}
        inline T top(){return seq[1];}
        void clear(){
            for(int i=1;i<(siz_m<<1);++i)seq[i]=T();
        }
        void set(size_t x,T val){
            seq[siz_m+x]=val;
            for(int i=siz_m+x>>1;i;i>>=1)seq[i]=upd(seq[i<<1],seq[i<<1|1]);
        }
        void update(size_t x,T val){set(x,upd(seq[siz_m+x],val));}
        T query(int l,int r){
            T res=upd(seq[l+siz_m],seq[r+siz_m]);
            for(l+=siz_m,r+=siz_m;l^r^1;l>>=1,r>>=1){
                if(~l&1)res=upd(res,seq[l^1]);
                if( r&1)res=upd(res,seq[r^1]);
            }
            return res;
        }
    };
}
using namespace simpler;
using ll=long long;
const int Maxn=5e5+5;
ll a[Maxn<<1];
struct updater{
    ll operator()(ll a,ll b){return max(a,b);}
};
int main(){
    int n=readu();
    segtree<ll,vector<ll>,updater>seg(n<<1);
    for(int i=1;i<=n;++i)a[i]=a[i+n]=readu();
    for(int i=1;i<=(n<<1);++i)a[i]+=a[i-1];
    int l=1,r=n>>1,cnt=0;
    while(r<=(n<<1)){
        seg.set(l,a[r]-a[l-1]);
        ++l,++r;
    }
    ll ans=0;
    for(int i=1;i<=n;++i)
        umax(ans,a[n]-seg.query(i+1,i+(n+1>>1)));
    cout<<ans<<'\n';
    return 0;
}
posted @ 2022-08-10 14:57  AlienCollapsar  阅读(65)  评论(0)    收藏  举报
// 生成目录索引列表 // ref: http://www.cnblogs.com/wangqiguo/p/4355032.html // modified by: zzq