模板集合


Basic

通用模板

#include 
using namespace std;

typedef long long ll;
typedef vector vi;
typedef pair pii;

template
inline T read(){
    T x=0,f=0;char ch=getchar();
    while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
    while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    return f?-x:x;
}

#define rdi read
#define rdll read
#define fi first
#define se second
#define pb push_back
#define mp make_pair

int main(){
#ifdef LOCAL
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
#endif
    return 0;
}

读入优化

namespace GTR {
    const int bufl = 1 << 15;
    char buf[bufl], *s = buf, *t = buf;
    inline int fetch() {
        if (s == t) { t = (s = buf) + fread(buf, 1, bufl, stdin); if (s == t) return EOF; }
        return *s++;
    }
    inline int read() {
        int a = 0, b = 1, c = fetch();
        while (c < 48 || c > 57) b ^= c == '-', c = fetch();
        while (c >= 48 && c <= 57) a = (a << 1) + (a << 3) + c - 48, c = fetch();
        return b ? a : -a;
    }
} using GTR::read;

DS

Segment Tree Beats

区间取 min,区间加,区间求和。

struct Node{
    ll mx,smx,sum;
    int cnt;
    friend Node operator + (Node a,Node b){
        if(!a.cnt1) return b;
        if(!b.cnt1) return a;
        if(a.mxb.mx) return {a.mx,max(a.smx,b.mx),a.sum+b.sum,a.cnt};
        else return {a.mx,max(a.smx,b.smx),a.sum+b.sum,a.cnt+b.cnt};
    }
}t[N*4];
ll tmx[N*4],tsum[N*4];
void pushup(int now) {t[now]=t[lson]+t[rson];}
void upd1(int now,ll t1){
    if(t[now].mxy||val>=t[now].mx) return;
    if(x<=l&&r<=y&&val>t[now].smx) return upd1(now,val);
    if(l==r) {t[now].mx=min(t[now].mx,val),t[now].sum=t[now].mx;return;}
    pushdown(now);
    if(x<=mid) chkmin(lson,l,mid,x,y,val);
    if(y>mid) chkmin(rson,mid+1,r,x,y,val);
    pushup(now);
}
void query(){
    //与普通线段树相同
}

李超树

支持插入直线,查询,合并。

struct Line{
    ll k,b;
    ll operator ()(ll x) const{return k*x+b;}
};

struct SGT{
#define lson (t[now].ls)
#define rson (t[now].rs)
#define mid ((l+r)>>1)
    struct Node{Line cur;int ls,rs;}t[N*60];
    int tot;

    int newnode(){
        t[++tot]={{0,INFl},0,0};
        return tot;
    }
    void insert(int &now,int l,int r,Line x){
        if(!now) now=newnode();
        if(t[now].cur(mid)>x(mid)) swap(t[now].cur,x);
        if(l==r) return;
        if(x(l)

历史最值线段树

支持区间加减,单点修改(区间赋值以后补)。

struct SGT{
#define lson (now<<1)
#define rson (now<<1|1)
#define mid ((l+r)>>1)
    struct Node{ll mx,hmx,ad,h_ad;}t[N*4];
    void upd(int now,ll ad,ll h_ad){
        t[now].hmx=max(t[now].mx+h_ad,t[now].hmx),t[now].mx+=ad;
        t[now].h_ad=max(t[now].h_ad,t[now].ad+h_ad),t[now].ad+=ad;
    }
    void pushdown(int now){
        if(t[now].ad||t[now].h_ad){
            upd(lson,t[now].ad,t[now].h_ad),upd(rson,t[now].ad,t[now].h_ad);
            t[now].ad=t[now].h_ad=0;
        }
    }
    void pushup(int now){
        t[now].mx=max(t[lson].mx,t[rson].mx);
        t[now].hmx=max({t[now].mx,t[lson].hmx,t[rson].hmx});
    }

    void build(int now,int l,int r){
        t[now].mx=t[now].hmx=-INFl;
        if(l==r) return;
        build(lson,l,mid);build(rson,mid+1,r);
    }
    void add(int now,int l,int r,int x,int y,ll val){
        if(x<=l&&r<=y) {upd(now,val,max(val,0ll));return;}
        pushdown(now);
        if(x<=mid) add(lson,l,mid,x,y,val);
        if(y>mid) add(rson,mid+1,r,x,y,val);
        pushup(now);
    }
    void set(int now,int l,int r,int x,ll val){
        if(l==r){
            t[now].mx=val;
            t[now].hmx=max(t[now].hmx,t[now].mx);
            return;
        }
        pushdown(now);
        x<=mid?set(lson,l,mid,x,val):set(rson,mid+1,r,x,val);
        pushup(now);
    }
    ll query(int now,int l,int r,int x,int y){
        if(x<=l&&r<=y) return t[now].hmx;
        ll ret=-INFl;pushdown(now);
        if(x<=mid) ret=max(ret,query(lson,l,mid,x,y));
        if(y>mid) ret=max(ret,query(rson,mid+1,r,x,y));
        return ret;
    }
#undef lson
#undef rson
#undef mid
};