Loading

数据结构板子

st表

int query(int l, int r) {
    int k = __lg(r - l + 1);
    return __gcd(st[l][k], st[r - (1 << k) + 1][k]);
}
void solve() {
    // 此处维护区间gcd
    for(int i = 1; i <= n; i++) {
        st[i][0] = abs(a[i + 1] - a[i]);
    }
    for(int k = 1; k <= __lg(n); k++) {
        for(int i = 1; i + (1 << k) - 1 <= n; i++) {
            st[i][k] = __gcd(st[i][k - 1], st[i + (1 << k - 1)][k - 1]);
        }
    }
}

树状数组

// 此题开了21个树状数组,非常恶心
int tr[22][K + 10];
int lowbit(int x) {
    return x & -x;
}
void update(int i, int x, int d) {
    x++;
    while(x <= K) {
        tr[i][x] += d;
        x += lowbit(x);
    }
}
int qu(int i, int x) {
    x++;
    int ans = 0;
    while(x) {
        ans += tr[i][x];
        x -= lowbit(x);
    }
    return ans;
}
int query(int i, int l, int r) {
    return qu(i, r) - qu(i, l - 1);
}

动态开点线段树

void update(int i, ll l, ll r, ll q, int x) {
    num[i] = x;
    if(l == r) return;
    ll mid = (l + r) / 2;
    if(q <= mid) {
        if(!ls[i]) ls[i] = ++cnt;
        update(ls[i], l, mid, q, x);
    } else {
        if(!rs[i]) rs[i] = ++cnt;
        update(rs[i], mid + 1, r, q, x);
    }
}

树链剖分

ll w0[N];
int dep[N], f[N], sz[N], son[N];
void dfs1(int l, int i) {
    f[i] = l;
    dep[i] = dep[l] + 1;
    int ms = -1;
    for(int j = 0; j < v[i].size(); j++) {
	int t = v[i][j];
	if(t == l) continue;
	dfs1(i, t);
	sz[i] += sz[t] + 1;
	if(sz[t] > ms) {
	    ms = sz[t];
	    son[i] = t;
	}
    }
}
int id[N], z, up[N];
ll w[N];
void dfs2(int i, int iup) {
    z++;
    id[i] = z;
    w[z] = w0[i];
    up[i] = iup;
    if(son[i] == 0) return;
    dfs2(son[i], iup);
    for(int j = 0; j < v[i].size(); j++) {
	int t = v[i][j];
	if(t == f[i] || t == son[i]) continue;
	dfs2(t, t);
    }
}
ll sum[N * 4], lz[N * 4];
void pushup(int i) {
    sum[i] = sum[i * 2] + sum[i * 2 + 1];
    sum[i] %= mo;
}
void build(int i, int l, int r) {
    if(l == r) {
	sum[i] = w[l];
	return;
    }
    int mid = (l + r) / 2;
    build(i * 2, l, mid);
    build(i * 2 + 1, mid + 1, r);
    pushup(i);
}
void pushdown(int i, int l, int r) {
    if(lz[i]) {
	int mid = (l + r) / 2;
	sum[i * 2] += (mid - l + 1) * lz[i];
	sum[i * 2] %= mo;
	sum[i * 2 + 1] += (r - mid) * lz[i];
	sum[i * 2 + 1] %= mo;
	lz[i * 2] += lz[i];
	lz[i * 2] %= mo;
	lz[i * 2 + 1] += lz[i];
	lz[i * 2 + 1] %= mo;
	lz[i] = 0;
    }
}
void modify(int i, int l, int r, int ql, int qr, ll d) {
    if(ql <= l && qr >= r) {
	sum[i] += (r - l + 1) * d;
	sum[i] %= mo;
	lz[i] += d;
	lz[i] %= mo;
	return;
    }
    pushdown(i, l, r);
    int mid = (l + r) / 2;
    if(ql <= mid) modify(i * 2, l, mid, ql, qr, d);
    if(qr > mid) modify(i * 2 + 1, mid + 1, r, ql, qr, d);
    pushup(i);
}
ll query(int i, int l, int r, int ql, int qr) {
    if(ql <= l && qr >= r) return sum[i];
    pushdown(i, l, r);
    int mid = (l + r) / 2;
    ll ans = 0;
    if(ql <= mid) ans += query(i * 2, l, mid, ql, qr);
    if(qr > mid) ans += query(i * 2 + 1, mid + 1, r, ql, qr);
    ans %= mo;
    pushup(i);
    return ans;
}
void op1(int x, int y, ll d) {
    while(up[x] != up[y]) {
	if(dep[up[x]] < dep[up[y]]) swap(x, y);
	modify(1, 1, n, id[up[x]], id[x], d);
	x = f[up[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    modify(1, 1, n, id[x], id[y], d);
}
ll op2(int x, int y) {
    ll ans = 0;
    while(up[x] != up[y]) {
	if(dep[up[x]] < dep[up[y]]) swap(x, y);
	ans += query(1, 1, n, id[up[x]], id[x]);
	ans %= mo;
	x = f[up[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    ans += query(1, 1, n, id[x], id[y]);
    ans %= mo;
    return ans;
}
posted @ 2024-09-07 13:32  Aderose_yr  阅读(15)  评论(2编辑  收藏  举报