数据结构模板

· · 算法·理论

这是一篇关于数据结构模板的文章 这些是其他模板分类的链接

字符串 数学 杂项 图论

并查集


# ST 表
- [P3865 【模板】ST 表](https://www.luogu.com.cn/problem/P3865)
```cpp
int n,a[N],dp[L][N];

void init(){
    for(int i=1; i<=n; i++) dp[0][i]=a[i];

    int t=log2(n);
    for(int i=1; i<=t; i++){
        for(int j=1; j+(1<<i)-1<=n; j++) dp[i][j]=max(dp[i-1][j],dp[i-1][j+(1<<i-1)]);
    }
}

int query(int l, int r){
    int t=log2(r-l+1);
    return max(dp[t][l],dp[t][r-(1<<t)+1]);
}

树状数组

单点修改,区间查询

class fen{ int c[N];

int sum(int x){
    int s=0;
    for(int i=x; i; i&=i-1) s+=c[i];
    return s;
}

public:

void update(int p, int x){
    for(int i=p; i<=n; i+=i&-i) c[i]+=x;
}

int query(int l, int r){
    return sum(r)-sum(l-1);
}

};


## 区间修改,单点查询
- [P3368 【模板】树状数组 2](https://www.luogu.com.cn/problem/P3368)
```cpp
int n;

class fen{
    int c[N];

    void add(int p, int x){
        for(int i=p; i<=n; i+=i&-i) c[i]+=x;
    }

    public:

    void update(int l, int r, int x){
        add(l,x), add(r+1,-x);
    }

    int query(int x){
        int s=0;
        for(int i=x; i; i&=i-1) s+=c[i];
        return s;
    }
};

线段树

单种修改,单种查询

long long a[N];

class seg{ long long t[N<<2];

struct{
    int l,r;
    long long w;
}s[N<<2];

void add(int x, long long w){
    t[x]+=w, s[x].w+=w*(s[x].r-s[x].l+1);
}

void down(int x){
    if(t[x]) add(L,t[x]), add(R,t[x]), t[x]=0;
}

void up(int x){
    s[x].w=s[L].w+s[R].w;
}

public:

void build(int x, int l, int r){
    s[x]={l,r}, t[x]=0;
    if(l==r){
        s[x].w=a[l];
        return;
    }

    int m=l+r>>1;
    build(L,l,m), build(R,m+1,r);
    up(x);
}

void update(int x, int l, int r, long long w){
    if(s[x].l>r || s[x].r<l) return;
    if(s[x].l>=l && s[x].r<=r){
        add(x,w);
        return;
    }

    down(x);
    update(L,l,r,w), update(R,l,r,w);
    up(x);
}

long long query(int x, int l, int r){
    if(s[x].l>r || s[x].r<l) return 0;
    if(s[x].l>=l && s[x].r<=r) return s[x].w;

    down(x);
    return query(L,l,r)+query(R,l,r);
}

};


## 多种修改,单种查询
- [P3373 【模板】线段树 2](https://www.luogu.com.cn/problem/P3373)
```cpp
#define L x<<1
#define R x<<1|1

long long a[N],MOD;

class seg{
    long long t1[N<<2],t2[N<<2];

    struct{
        int l,r;
        long long w;
    }s[N<<2];

    void add(int x, long long w, bool f){
        if(f) t1[x]=t1[x]*w%MOD, t2[x]=t2[x]*w%MOD, s[x].w=s[x].w*w%MOD;
        else t2[x]=(t2[x]+w)%MOD, s[x].w=(s[x].w+w*(s[x].r-s[x].l+1))%MOD;
        return;
    }

    void down(int x){
        if(t1[x]!=1) add(L,t1[x],1), add(R,t1[x],1), t1[x]=1;
        if(t2[x]) add(L,t2[x],0), add(R,t2[x],0), t2[x]=0;
    }

    void up(int x){
        s[x].w=(s[L].w+s[R].w)%MOD;
    }

    public:

    void build(int x, int l, int r){
        s[x]={l,r}, t1[x]=1, t2[x]=0;
        if(l==r){
            s[x].w=a[l]%MOD;
            return;
        }

        int m=l+r>>1;
        build(L,l,m), build(R,m+1,r);
        up(x);
    }

    void update(int x, int l, int r, long long w, bool f){
        if(s[x].l>r || s[x].r<l) return;
        if(s[x].l>=l && s[x].r<=r){
            add(x,w,f);
            return;
        }

        down(x);
        update(L,l,r,w,f), update(R,l,r,w,f);
        up(x);
    }

    long long query(int x, int l, int r){
        if(s[x].l>r || s[x].r<l) return 0;
        if(s[x].l>=l && s[x].r<=r) return s[x].w;

        down(x);
        return (query(L,l,r)+query(R,l,r))%MOD;
    }
};

多种修改,多种查询

int a[N];

struct node{ int l,r,c,s0,s1,sl,sr; bool fl,fr;

node operator +(node x){
    node t={l,x.r,c+x.c,max(s0,x.s0),max(s1,x.s1),sl,x.sr,fl,x.fr};

    if(fr && x.fl){
        t.s1=max(t.s1,sr+x.sl);
        if(sl==r-l+1) t.sl+=x.sl;
        if(x.sr==x.r-x.l+1) t.sr+=sr;
    }
    else if(!fr && !x.fl){
        t.s0=max(t.s0,sr+x.sl);
        if(sl==r-l+1) t.sl+=x.sl;
        if(x.sr==x.r-x.l+1) t.sr+=sr;
    }

    return t;
}

};

class seg{ int t[N<<2]; node s[N<<2];

void add(int x, int w){
    if(w==2){
        t[x]= t[x]==2 ? -1 : ~t[x] ? !t[x] : 2;
        s[x].fl=!s[x].fl, s[x].fr=!s[x].fr, s[x].c=s[x].r-s[x].l-s[x].c+1, swap(s[x].s0,s[x].s1);
    }
    else if(~w){
        t[x]=s[x].fl=s[x].fr=w, s[x].sl=s[x].sr=s[x].r-s[x].l+1;
        if(w) s[x].c=s[x].s1=s[x].r-s[x].l+1, s[x].s0=0;
        else s[x].s0=s[x].r-s[x].l+1, s[x].c=s[x].s1=0;
    }
}

void down(int x){
    if(~t[x]) add(L,t[x]), add(R,t[x]), t[x]=-1;
}

void up(int x){
    s[x]=s[L]+s[R];
}

public:

void build(int x, int l, int r){
    s[x]={l,r}, t[x]=-1;
    if(l==r){
        s[x].fl=s[x].fr=s[x].c=s[x].s1=a[l], s[x].s0=!a[l], s[x].sl=s[x].sr=1;
        return;
    }

    int m=l+r>>1;
    build(L,l,m), build(R,m+1,r);
    up(x);
}

void update(int x, int l, int r, int w){
    if(s[x].l>r || s[x].r<l) return;
    if(s[x].l>=l && s[x].r<=r){
        add(x,w);
        return;
    }

    down(x);
    update(L,l,r,w), update(R,l,r,w);
    up(x);
}

node query(int x, int l, int r){
    if(s[x].l>r || s[x].r<l) return {s[x].l,s[x].r};
    if(s[x].l>=l && s[x].r<=r) return s[x];

    down(x);
    return query(L,l,r)+query(R,l,r);
}

};