数据结构

树状数组:

template<typename T>
struct BIT{
    T a[N];
    int size = N;
    void init(int s){
        size = s;
        for(int i = 0; i <= s; i++){
            a[i] = 0;
        }
    }
    T query(int x){
        assert(x <= size);
        T s = 0;
        for(; x; x -= x&(-x)){
            s += a[x];
        }
        return s;
    }
    void modify(int x,T s){
        assert(x != 0);
        for(; x <= N; x += x&(-x)){
            a[x] += s;
        }
    }    
};
BIT<int> bit;

线段树(单点修改最小值)

template<typename T>
struct SegmentTree{
    T a[N];
    struct node{
        T va;
    }seg[4 * N];
    void init(int v = 0){
        for(int i = 0; i < N; i++) a[i] = v;
    }
    void update(int id){
        seg[id].va = min(seg[id*2].va, seg[id*2+1].va);
    }
    void build(int id, int l, int r){
        if (l == r) {
            seg[id].va = a[l];
        } else {
            int mid = (l + r) / 2;
            build(id*2, l, mid);
            build(id*2+1, mid + 1, r);
            update(id);
        }
    }
    void change (int id, int l, int r, int pos, T val) {
        if (l == r) {
            seg[id].va = val;
        } else {
            int mid = (l + r) / 2;
            if(pos <= mid) change(id * 2, l, mid, pos, val);
            else change(id * 2 + 1, mid + 1, r, pos, val);
            update(id);
        }
    }
    T query(int id, int l, int r, int ql, int qr){
        if(l==ql && r == qr) return seg[id].va;
        int mid = (l + r) / 2;
        if(qr <= mid) return query(id * 2, l ,mid, ql, qr);
        else if(ql > mid){return query(id * 2 + 1, mid + 1, r, ql, qr);}
        else{
            return min(query(id * 2, l ,mid, ql, mid), query(id * 2 + 1, mid + 1, r, mid+1, qr));
        }
    }
};
SegmentTree<ll> Seg;

线段树(区间修改区间和)

template<typename T>
struct SegmentTree{
    T a[N];
    void init(int v = 0) {for(int i = 0; i < N; i++) a[i] = v;}
    struct tag{T mul, add; };
    struct node{
        tag t; T val;
        int sz;
    }seg[4*N];
    friend tag operator+ (const tag &t1, const tag &t2) {
        return  {t1.mul * t2.mul % mod , (t1.add * t2.mul + t2.add)%mod};
    }
    void update(int id) {
        seg[id].val = (seg[id * 2].val + seg[id * 2 + 1].val) % mod;
    }
    void settag(int id, tag t) {
        seg[id].t = seg[id].t + t;
        seg[id].val = (seg[id].val * t.mul + seg[id].sz * t.add) % mod;
    }
    void pushdown(int id) {
        if(seg[id].t.mul!=1||seg[id].t.add!=0){
            settag(id*2, seg[id].t);
            settag(id*2+1, seg[id].t);
            seg[id].t.mul = 1;
            seg[id].t.add = 0;
        }
    }
    void build(int id, int l, int r) {
        seg[id].t = {1,0}; seg[id].sz = r - l + 1;
        if (l == r) {
            seg[id].val = {a[l]};
        } else {
            int mid = (l + r) / 2;
            build(id * 2, l, mid); build(id * 2 + 1, mid + 1, r);
            update(id);
        }
    }
    void modify(int id, int l, int r, int ql, int qr, tag t) {
        if (l == ql && r == qr) {
            settag(id, t);
            return;
        }
        int mid = (l + r) / 2;
        pushdown(id);
        if (qr <= mid) modify(id * 2, l, mid, ql, qr, t);
        else if (ql > mid) modify(id * 2+1, mid + 1, r, ql, qr, t);
        else{
            modify(id * 2, l, mid, ql, mid, t);
            modify(id * 2 + 1,  mid + 1, r, mid + 1, qr ,t);
        }
        update(id);
    }
    void change(int id, int l, int r, int pos, T val) {
        if (l == r) {
            seg[id].val = {val};
        }else{
            int mid = (l + r) / 2;
            if(pos <= mid) change(id * 2, l, mid, pos, val);
            else change(id * 2 + 1, mid + 1, r, pos, val);
            update(id);
        }
    }
    T query(int id, int l, int r, int ql, int qr){
        if (l==ql && r == qr) return seg[id].val;
        int mid = (l + r) / 2;
        pushdown(id);
        if (qr <= mid) return query(id * 2, l ,mid, ql, qr);
        else if (ql > mid) return query(id * 2 + 1, mid + 1, r, ql, qr);
        else return (query(id * 2, l ,mid, ql,mid) + query(id * 2 + 1, mid + 1, r, mid+1, qr))%mod;
    }
};
SegmentTree<ll> Seg;

线段树上二分

int search(int id,int l,int r,int ql,int qr,int x){
    if(l==ql&&r==qr){
        if(seg[id].val<x) return -1;
        else{
            if(l==r) return l;
            int mid=(l+r)/2;
            if(seg[id*2].val>=x) return search(id*2,l,mid,ql,mid,x);
            else return search(id*2+1,mid+1,r,mid+1,qr,x);
        }
    }
    int mid = (l+r)/2;
    if(qr<=mid) return search(id*2,l,mid,ql,qr,x);
    else if(ql>mid) return search(id*2+1,mid+1,r,ql,qr,x);
    else{
        int pos = search(id*2,l,mid,ql,mid,x);
        if(pos==-1) return search(id*2+1,mid+1,r,mid+1,qr,x);
        else return pos;
    }
}//not sort

莫队

int q,res;array<int,3>que[N];
void add(int x){}
void del(int x){}
int calc(){ return res;}
vector<int> Mo(){
    res=0;int B=500;//sqrt(Q)
    vector<int> ans(q+1);
    sort(que+1,que+q+1,[&](array<int,3> a,array<int,3> b){
        int c=a[0]/B;
        if(c!=b[0]/B) return c<b[0]/B;
        return c%2?a[1]>b[1]:a[1]<b[1];
    });
    int l=1,r=0;
    for(int i=1;i<=q;i++){
        while(r<que[i][1]) r++,add(r);
        while(l>que[i][0]) l--,add(l);
        while(r>que[i][1]) del(r),r--;
        while(l<que[i][0]) del(l),l++;
        ans[que[i][2]]=calc();    
    }
    while(l<=r) del(l++);
    return ans;
}

并查集

struct DSU {
    vector<int> f, siz;
    
    DSU() {}
    DSU(int n) {
        init(n);
    }
    
    void init(int n) {
        f.resize(n);
        std::iota(f.begin(), f.end(), 0);
        siz.assign(n, 1);
    }
    
    int find(int x) {
        while (x != f[x]) {
            x = f[x] = f[f[x]];
        }
        return x;
    }
    
    bool same(int x, int y) {
        return find(x) == find(y);
    }
    
    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) {
            return false;
        }
        siz[x] += siz[y];
        f[y] = x;
        return true;
    }
    
    int size(int x) {
        return siz[find(x)];
    }
};

LCA(倍增)

int n, m;
vector<int> e[N];
int root, fa[N][21], dep[N];
bool vis1[N];

void dfs(int x) {
    vis1[x] = 1;
    for (auto y : e[x]) if (!vis1[y]) {
        fa[y][0] = x;
        dep[y] = dep[x] + 1;
        dfs(y);
    }
}
void LCA_init(int x){
    root = x;
    memset(dep, 0, sizeof dep);
    dfs(root);
    for(int i = 1; i <= 20; i++){
        for(int j = 1; j <= n; j++){
            if(fa[j][i - 1]) {
                fa[j][i] = fa[fa[j][i - 1]][i - 1];
            }
        }
    }
}
int LCA(int x, int y) {
    if(dep[x] < dep[y]) swap(x, y);
    int z = dep[x] - dep[y];
    for(int j = 0; j <= 20 && z; j++, z/=2) {
        if(z & 1) x = fa[x][j];
    }
    if(x == y) return x;
    for(int j = 20; j >= 0; j--){
        if(fa[x][j] != fa[y][j]){
            x = fa[x][j], y = fa[y][j];
        }
    }
    return fa[x][0];
}

LCA(树链剖分)

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 101000;
//O(n) - O(lgn)
int n;
std::vector<int> e[N];
int l[N], r[N], id[N];
int sz[N], hs[N], tot, top[N], dep[N], fa[N];

void dfs1(int u, int f){
    sz[u] = 1;
    hs[u] = -1;
    fa[u] = f;
    dep[u] = dep[f] + 1;
    for(auto v : e[u]){
        if(v == f) continue;
        dfs1(v, u);
        sz[u] += sz[u];
        if(hs[u] == -1 || sz[v] > sz[hs[u]]){
            hs[u] = v;
        }
    }
}

void dfs2(int u, int t){
    top[u] = t;
    l[u] = ++tot;
    id[tot] = u;
    if(hs[u] != -1){
        dfs2(hs[u], t);
    }
    for(auto  v : e[u]) {
        if(v != fa[u] && v != hs[u]) {
            dfs2(v, v);
        }
    }
    r[u] = tot;
}
int LCA(int u, int v){
    while(top[u] != top[v]){
        if(dep[top[u]] < dep[top[v]]) v=fa[top[v]];
        else u = fa[top[u]];
    }
    if(dep[u] < dep[v]) return u;
    else return v;    
}
void work(){
    dfs1(1,0);dfs2(1,1)
}
int main() {
    cin>>n;
    for(int i = 1; i <= n; i++){
        int u, v; cin >> u >> v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    work();
    int a, b; cin >> a >> b;
    cout << LCA(a, b); 
}

树链剖分(重链)

struct HLD{
    int n,tot;
    std::vector<std::vector<int>> e;
    std::vector<int> l, r, id;
    std::vector<int> sz, hs, top, dep, fa;
    HLD() {}
    HLD(int n) {
        init(n);
    }
    void init(int n) {
        this->n = n;n++;
        sz.resize(n);
        hs.resize(n);
        top.resize(n);
        dep.resize(n);
        fa.resize(n);
        l.resize(n);
        r.resize(n);
        id.resize(n);
        tot = 0;
        e.assign(n, {});
    }
    void addEdge(int u, int v){
        e[u].push_back(v);
        e[v].push_back(u);
    }
    void work(int root = 1){
        top[root] = root;
        dep[root] = 0;
        fa[root] = -1;
        dfs1(root,0);
        dfs2(root,root);
    }
    void dfs1(int u, int f){
        sz[u] = 1;
        hs[u] = -1;
        fa[u] = f;
        dep[u] = dep[f] + 1;
        for(auto v : e[u]){
            if(v == f) continue;
            dfs1(v, u);
            sz[u] += sz[v];
            if(hs[u] == -1 || sz[v] > sz[hs[u]]){
                hs[u] = v;
            }
        }
    }
    void dfs2(int u, int t){
        top[u] = t;
        l[u] = ++tot;
        id[tot] = u;
        if(hs[u] != -1){
            dfs2(hs[u], t);
        }
        for(auto  v : e[u]) {
            if(v != fa[u] && v != hs[u]) {
                dfs2(v, v);
            }
        }
        r[u] = tot;
    }
    int LCA(int u, int v){
        while(top[u] != top[v]){
            if(dep[top[u]] < dep[top[v]]) v=fa[top[v]];
            else u = fa[top[u]];
        }
        if(dep[u] < dep[v]) return u;
        else return v;    
    }
    int dist(int u, int v){
        return dep[u] + dep[v] - 2 * dep[LCA(u, v)];
    }
    int jump(int u, int k){
        if(dep[u] < k) {
            return -1;
        }
        int d = dep[u] - k;
        while(dep[top[u]] > d){
            u = fa[top[u]];
        }
        return id[l[u] - dep[u] + d];
    }
     bool isAncester(int u, int v) {
        return l[u] <= l[v] && l[v] < r[u];
    }
    int rootedChild(int u, int v) {
        if (u == v) {
            return u;
        }
        if (!isAncester(u, v)) {
            return fa[u];
        }
        auto it = std::upper_bound(e[u].begin(), e[u].end(), v, [&](int x, int y) {
            return l[x] < l[y];
        }) - 1;
        return *it;
    }
    int rootedSize(int u, int v) {
        if (u == v) {
            return n;
        }
        if (!isAncester(v, u)) {
            return sz[v];
        }
        return n - sz[rootedChild(v, u)];
    }
    int rootedLca(int a, int b, int c) {
        return LCA(a, b) ^ LCA(b, c) ^ LCA(c, a);
    }
};

树上启发式合并

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
vector<int>e[N];
int l[N],r[N],id[N],sz[N],hs[N],tot;

void dfs_init(int u,int f){
    l[u]=++tot;
    id[tot]=u;
    sz[u]=1;
    hs[u]=-1;
    for(auto v : e[u]){
        if(f==v) continue;
        dfs_init(v,u);
        sz[u]+=sz[v];
        if(hs[u]==-1||sz[v]>sz[hs[u]]){
            hs[u]=v;
        }
    }
    r[u]=tot;
}
void dfs_solve(int u,int f,bool keep){
    for(auto v:e[u]){
        if(v!=f&&v!=hs[u]){
            dfs_solve(v,u,false);
        }
    }
    if(hs[u]!=-1){
        dfs_solve(hs[u],u,true);
    }
    for(auto v:e[u]){
        if(v!=f&&v!=hs[u]){
            for(int x=l[v];x<=r[v];x++){
                add(id[x]);
            }
        }
    }
    add(u);
    if(!keep){//清空
        for(int x=l[u];x<=r[u];x++){
                del(id[x]);
        }
    }
}

int main(){

    return 0;
}

ST表

/*
预处理区间
把一段区间分成两个2的幂次区间的覆盖,用于与自己做运算不变的运算如gcd,max,min,^等\
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=1010000,LOGN=20;
int n,q,lg[N];
int A,B,C,l,r,a[N],f[N][22];

void init_ST(){
    for(int j=1;j<=LOGN;j++){
        for(int i=1;i+(1<<j)-1<=n;i++){
            f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
        }
    }
    lg[1]=0;
    for(int i=2;i<=n;i++) lg[i]=lg[i/2]+1;//预处理x取log下取整
}

int main(){
    scanf("%d%d%u%u%u",&n,&q,&A,&B,&C);
    int ans=0;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        f[i][0]=a[i];
    }
    for(int i=1;i<=q;i++){
        scanf("%u%u",&l,&r);
        int len=lg[r-l+1];
        ans^=max(f[l][len],f[r-(1<<len)+1][len]);
    }

    return 0;
}

 

posted @ 2024-03-21 19:36  Miburo  阅读(16)  评论(0)    收藏  举报