• 线段树模板


    线段树模板。

    链接

    Luogu 3373

    代码

    #include <cstdio>
    
    typedef long long ll;
    
    const int SIZE = 100005;
    
    inline char gc() {
    	static char buf[SIZE], *p1 = buf + SIZE, *p2 = buf + SIZE;
    	if (p1 == p2) p2 = (p1 = buf) + fread(buf, 1, SIZE, stdin);
    	return p1 == p2 ? -1 : *p1++;
    }
    
    inline ll read() {
    	char ch = 0;
    	ll sum = 0, s = 1;
    	while (!(ch >= '0' && ch <= '9')) if ((ch = gc()) == '-') s = -1;
    	while (ch >= '0' && ch <= '9') sum = (sum << 3) + (sum << 1) + ch - 48, ch = gc();
    	return sum * s;
    }
    
    ll n, m, opt;
    ll P, num[SIZE];
    struct SegTree {
    	ll r, l, add;
    	ll sum, mul;
    };
    SegTree tree[SIZE << 2];
    
    inline void pushDown(ll p);
    inline ll ask(ll p, ll l, ll r);
    inline void build(ll p, ll l, ll r);
    inline void initNode(ll p, ll l, ll r);
    inline void mulChange(ll p, ll l, ll r, ll k);
    inline void addChange(ll p, ll l, ll r, ll k);
    
    inline void pushDown(ll p) {
    	if (tree[p].add || tree[p].mul != 1) {
    		tree[p << 1].sum = (tree[p << 1].sum * tree[p].mul) % P;
    		tree[p << 1 | 1].sum = (tree[p << 1 | 1].sum * tree[p].mul) % P;
    		tree[p << 1].sum = (tree[p << 1].sum + (tree[p << 1].r - tree[p << 1].l + 1) * tree[p].add) % P;
    		tree[p << 1 | 1].sum = (tree[p << 1 | 1].sum + (tree[p << 1 | 1].r - tree[p << 1 | 1].l + 1) * tree[p].add) % P;
    		tree[p << 1].mul = (tree[p << 1].mul * tree[p].mul) % P;
    		tree[p << 1 | 1].mul = (tree[p << 1 | 1].mul * tree[p].mul) % P;
    		tree[p << 1].add = (tree[p].add + (tree[p << 1].add * tree[p].mul)) % P;
    		tree[p << 1 | 1].add = (tree[p].add + (tree[p << 1 | 1].add * tree[p].mul)) % P;
    		tree[p].add = 0, tree[p].mul = 1;
    	}
    	return;
    }
    
    inline ll ask(ll p, ll l, ll r) {
    	if (l <= tree[p].l && tree[p].r <= r) {
    		return tree[p].sum % P;
    	}
        pushDown(p);
    	ll res = 0, mid = (tree[p].l + tree[p].r) >> 1;
    	if (l <= mid) res = res + ask(p << 1, l, r);
    	if (r > mid) res = res + ask(p << 1 | 1, l, r);
    	return res % P;
    }
    
    inline void build(ll p, ll l, ll r) {
    	initNode(p, l, r);
    	if (l == r) {
    		tree[p].sum = num[l];
    		return;
    	}
    	ll mid = (l + r) >> 1;
    	build(p << 1, l, mid);
    	build(p << 1 | 1, mid + 1, r);
    	tree[p].sum = (tree[p << 1].sum + tree[p << 1 | 1].sum) % P;
    }
    
    inline void initNode(ll p, ll l, ll r) {
    	tree[p].add = 0, tree[p].mul = 1;
    	tree[p].l = l, tree[p].r = r;
    }
    
    inline void mulChange(ll p, ll l, ll r, ll k) {
    	if (l <= tree[p].l && tree[p].r <= r) {
    		tree[p].mul = (tree[p].mul * k) % P;
    		tree[p].add = (tree[p].add * k) % P;
    		tree[p].sum = (tree[p].sum * k) % P;
    		return;
    	}
    	pushDown(p);
    	ll mid = (tree[p].l + tree[p].r) >> 1;
    	if (l <= mid) mulChange(p << 1, l, r, k);
    	if (r > mid) mulChange(p << 1 | 1, l, r, k);
    	tree[p].sum = (tree[p << 1].sum + tree[p << 1 | 1].sum) % P;
    	return;
    }
    
    inline void addChange(ll p, ll l, ll r, ll k) {
    	if (l <= tree[p].l && tree[p].r <= r) {
    		tree[p].sum = (tree[p].sum + (tree[p].r - tree[p].l + 1) * k) % P;
    		tree[p].add = (tree[p].add + k % P) % P;
    		return;
    	}
    	pushDown(p);
    	ll mid = (tree[p].l + tree[p].r) >> 1;
    	if (l <= mid) addChange(p << 1, l, r, k);
    	if (r > mid) addChange(p << 1|1, l, r, k);
    	tree[p].sum = (tree[p << 1].sum + tree[p << 1 | 1].sum) % P;
    	return;
    }
    
    int main() {
    	ll opt, a, b, k;
    	n = read(), m = read(), P = read();
    	for (ll i = 1; i <= n; i++) num[i] = read();
    	build(1, 1, n);
    	for (ll i = 1; i <= m; i++) {
    		opt = read(), a = read(), b = read();
    		if (opt == 1) k = read(), mulChange(1, a, b, k);
    		if (opt == 2) k = read(), addChange(1, a, b, k);
    		if (opt == 3) printf("%lld
    ", (ask(1, a, b) % P + P) % P);
    	}
    	return 0;
    }
    
  • 相关阅读:
    题解【JOI 2020/2021 二次予選】B
    求导公式
    题解【洛谷P6875】[COCI2013-2014#6] KRUŽNICE
    二项式反演小记
    Matrix-Tree 定理小记
    2020ICPC南京D. Degree of Spanning Tree
    Codeforces Round #712 (Div. 1) C. Travelling Salesman Problem
    2021湖南多校对抗赛第四场 I
    2021湖南多校对抗赛第二场 C
    2021湖南多校对抗赛第二场 B
  • 原文地址:https://www.cnblogs.com/lcfsih/p/14391367.html
Copyright © 2020-2023  润新知