zoukankan      html  css  js  c++  java
  • 洛谷 P3373 【模板】线段树 2

    洛谷 P3373 【模板】线段树 2

    传送门

    根据一大堆不知名的神奇原理,我们先放乘法标记,再放加法标记(其实是我不知道咋说......)

    如果非要了解为什么先乘再加的话,click here-->

    主要就是区间乘,区间加以及区间求和,下面就放代码吧

    早期代码

    //知识点:线段树
    /*
    By:Loceaner
    */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define int long long
    using namespace std;
    
    inline int read() {
    	char c = getchar();
    	int x = 0, f = 1;
    	for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    	return x * f;
    }
    
    const int N = 1e5 + 11;
    
    int n, m, mod, a[N];
    
    struct node {
    	int sum, lazy1, lazy2, len;
    } t[N << 2];
    
    #define lson rt << 1
    #define rson rt << 1 | 1
    
    inline void pushup(int rt) {
    	t[rt].sum = (t[lson].sum + t[rson].sum) % mod;
    }
    
    void tag2(int rt, int k) {
    	t[rt].sum = t[rt].sum * k % mod;
    	t[rt].lazy2 *= k;
    	t[rt].lazy2 %= mod;
    	t[rt].lazy1 *= k;
    	t[rt].lazy1 %= mod;
    }
    
    void tag1(int rt, int k) {
    	t[rt].sum += t[rt].len * k;
    	t[rt].sum %= mod;
    	t[rt].lazy1 += k;
    	t[rt].lazy1 %= mod;
    }
    
    inline void pushdown(int rt) {
    	if(t[rt].lazy2 != 1) {
    		tag2(lson, t[rt].lazy2);
    		tag2(rson, t[rt].lazy2);
    		t[rt].lazy2 = 1;
    	}
    	if(t[rt].lazy1) {
    		tag1(lson, t[rt].lazy1);
    		tag1(rson, t[rt].lazy1);
    		t[rt].lazy1 = 0;
    	}
    }
    
    void build(int rt, int l, int r) {
    	t[rt].len = r - l + 1;
    	t[rt].lazy1 = 0, t[rt].lazy2 = 1;
    	if(l == r) {
    		t[rt].sum = read();
    		return;
    	}
    	int mid = (l + r) >> 1;
    	build(lson, l, mid);
    	build(rson, mid + 1, r);
    	pushup(rt);
    }
    
    void add(int rt, int l, int r, int L, int R, int x) {
    	if(L <= l && r <= R) return tag1(rt, x);
    	pushdown(rt);
    	int mid = (l + r) >> 1;
    	if(L <= mid) add(lson, l, mid, L, R, x);
    	if(R > mid) add(rson, mid + 1, r, L, R, x);
    	pushup(rt);
    }
    
    void mul(int rt, int l, int r, int L, int R, int x) {
    	if(L <= l && r <= R) return tag2(rt, x);
    	pushdown(rt);
    	int mid = (l + r) >> 1;
    	if(L <= mid) mul(lson, l, mid, L, R, x);
    	if(R > mid) mul(rson, mid + 1, r, L, R, x);
    	pushup(rt);
    }
    
    int query(int rt, int l, int r, int L, int R) {
    	int ans = 0;
    	if(L <= l && r <= R) {
    		ans += t[rt].sum;
    		return ans;
    	}
    	pushdown(rt);
    	int mid = (l + r) >> 1;
    	if(L <= mid) ans += query(lson, l, mid, L, R) % mod;
    	if(R > mid) ans += query(rson, mid + 1, r, L, R) % mod;
    	return ans % mod;
    }
    
    signed main() {
    	n = read(), m = read(), mod = read();
    	build(1, 1, n);
    	int opt, x, y, k;
    	while(m--) {
    		opt = read(), x = read(), y = read();
    		if(opt == 1) {
    			k = read();
    			mul(1, 1, n, x, y, k);
    		} else if(opt == 2) {
    			k = read();
    			add(1, 1, n, x, y, k);
    		} else cout << query(1, 1, n, x, y) % mod << '
    ';
    	}
    	return 0;
    }
    
    

    更新!

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define int long long
    using namespace std;
    
    const int A = 1e5 + 11;
    const int B = 1e6 + 11;
    
    inline int read() {
    	char c = getchar(); int x = 0, f = 1;
    	for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    	return x * f;
    }
    
    int n, m, mod;
    
    namespace Seg {
    	#define lson rt << 1
    	#define rson rt << 1 | 1
    	struct tre {
    		int l, r, w, lazy1, lazy2;
    	} t[A << 2];
    	inline void pushup(int rt) {
    		t[rt].w = (t[lson].w + t[rson].w) % mod;
    	}
    	inline void tag1(int rt, int val) {
    		t[rt].lazy1 *= val, t[rt].lazy2 *= val;
    		t[rt].lazy1 %= mod, t[rt].lazy2 %= mod;		
    		t[rt].w *= val, t[rt].w %= mod;
    	}
    	inline void tag2(int rt, int val) {
    		t[rt].lazy2 += val; t[rt].lazy2 %= mod;
    		t[rt].w += (t[rt].r - t[rt].l + 1) * val, t[rt].w %= mod;
    	}
    	inline void pushdown(int rt) {
    		if(t[rt].lazy1 != 1) {
    			tag1(lson, t[rt].lazy1);
    			tag1(rson, t[rt].lazy1);
    			t[rt].lazy1 = 1;
    		}
    		if(t[rt].lazy2) {
    			tag2(lson, t[rt].lazy2);
    			tag2(rson, t[rt].lazy2);
    			t[rt].lazy2 = 0;
    		}
    	}
    	inline void build(int rt, int l, int r) {
    		t[rt].l = l, t[rt].r = r, t[rt].lazy1 = 1, t[rt].lazy2 = 0;
    		if(l == r) { t[rt].w = read(); return; }
    		int mid = (l + r) >> 1;
    		build(lson, l, mid), build(rson, mid + 1, r);
    		pushup(rt); return;
    	}
    	inline void mul(int rt, int l, int r, int val) {
    		if(l <= t[rt].l && t[rt].r <= r) return tag1(rt, val);
    		pushdown(rt);
    		int mid = (t[rt].l + t[rt].r) >> 1;
    		if(l <= mid) mul(lson, l, r, val);
    		if(r > mid) mul(rson, l, r, val);
    		pushup(rt); return;
    	}
    	inline void update(int rt, int l, int r, int val) {
    		if(l <= t[rt].l && t[rt].r <= r) return tag2(rt, val);
    		pushdown(rt);
    		int mid = (t[rt].l + t[rt].r) >> 1;
    		if(l <= mid) update(lson, l, r, val);
    		if(r > mid) update(rson, l, r, val);
    		pushup(rt); return;
    	}
    	inline int query(int rt, int l, int r) {
    		if(l <= t[rt].l && t[rt].r <= r) { return t[rt].w % mod; }
    		pushdown(rt);
    		int mid = (t[rt].l + t[rt].r) >> 1, ans = 0;
    		if(l <= mid) ans += query(lson, l, r), ans %= mod;
    		if(r > mid) ans += query(rson, l, r), ans %= mod;
    		return ans % mod;
    	}
    }
    
    signed main() {
    	n = read(), m = read(), mod = read();
    	Seg::build(1, 1, n);
    	while(m--) {
    		int opt = read(), x = read(), y = read(), k;
    		if(opt == 1) k = read() % mod, Seg::mul(1, x, y, k);
    		else if(opt == 2) k = read() % mod, Seg::update(1, x, y, k);
    		else cout << Seg::query(1, x, y) % mod << '
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    Recon-Erlang线上系统诊断工具
    erlang pool模块。
    深度学习Bible学习笔记:第二、三章 线性代数 概率与信息论
    LeetCode(5):最长回文子串
    LeetCode(4):两个排序数组的中位数
    LeetCode(3):无重复字符的最长子串
    LeetCode(2):Add Two Numbers 两数相加
    LeetCode(1):两数之和
    深度学习Bible学习笔记:第一章 前言
    2018年3月18日论文阅读
  • 原文地址:https://www.cnblogs.com/loceaner/p/11112982.html
Copyright © 2011-2022 走看看