线段树2

Posted mrclr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树2相关的知识,希望对你有一定的参考价值。

这里发一下luogu线段树2的代码~~

技术分享图片
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<stack>
 10 #include<queue>
 11 using namespace std;
 12 #define enter puts("") 
 13 #define space putchar(‘ ‘)
 14 #define Mem(a) memset(a, 0, sizeof(a))
 15 typedef long long ll;
 16 typedef double db;
 17 const int INF = 0x3f3f3f3f;
 18 const int eps = 1e-8;
 19 const int maxn = 1e5 + 5;
 20 inline ll read()
 21 {
 22     ll ans = 0;
 23     char ch = getchar(), last =  ;
 24     while(!isdigit(ch)) {last = ch; ch = getchar();}
 25     while(isdigit(ch)) {ans = ans * 10 + ch - 0; ch = getchar();}
 26     if(last == -) ans = -ans;
 27     return ans;
 28 }
 29 inline void write(ll x)
 30 {
 31     if(x < 0) x = -x, putchar(-);
 32     if(x >= 10) write(x / 10);
 33     putchar(x % 10 + 0);
 34 }
 35 
 36 int n, m;
 37 ll mod;
 38 
 39 int l[maxn << 2], r[maxn << 2];
 40 ll sum[maxn << 2], lzy_add[maxn << 2], lzy_mul[maxn << 2];
 41 void build(int L, int R, int now)
 42 {
 43     l[now] = L; r[now] = R;
 44     lzy_mul[now] = 1;
 45     if(L == R) {sum[now] = read() % mod; return;}
 46     int mid = (L + R) >> 1;
 47     build(L, mid, now << 1); 
 48     build(mid + 1, R, now << 1 | 1);
 49     sum[now] = (sum[now << 1] + sum[now << 1 | 1]) % mod;
 50 }
 51 void pushdown(int now)
 52 {
 53     if(lzy_mul[now] != 1)
 54     {
 55         (lzy_mul[now << 1] *= lzy_mul[now]) %= mod;
 56         (lzy_mul[now << 1 | 1] *= lzy_mul[now]) %= mod;
 57         (lzy_add[now << 1] *= lzy_mul[now]) %= mod;
 58         (lzy_add[now << 1 | 1] *= lzy_mul[now]) %= mod;
 59         (sum[now << 1] *= lzy_mul[now]) %= mod;
 60         (sum[now << 1 | 1] *= lzy_mul[now]) %= mod;
 61         lzy_mul[now] = 1;
 62     }
 63     if(lzy_add[now])
 64     {
 65         (lzy_add[now << 1] += lzy_add[now]) %= mod;
 66         (lzy_add[now << 1 | 1] += lzy_add[now]) %= mod;
 67         (sum[now << 1] += lzy_add[now] * (r[now << 1] - l[now << 1] + 1)) %= mod;
 68         (sum[now << 1 | 1] += lzy_add[now] * (r[now << 1 | 1] - l[now << 1 | 1] + 1)) %= mod;
 69         lzy_add[now] = 0;
 70     }
 71 }
 72 void update(int L, int R, int now, ll d, bool flag)
 73 {
 74     if(l[now] == L && r[now] == R)
 75     {
 76         if(flag) sum[now] += d * (R - L + 1), lzy_add[now] += d;
 77         else sum[now] *= d, lzy_add[now] *= d, lzy_mul[now] *= d;
 78         sum[now] %= mod; lzy_add[now] %= mod; lzy_mul[now] %= mod;
 79         return;
 80     }
 81     pushdown(now);
 82     int mid = (l[now] + r[now]) >> 1;
 83     if(R <= mid) update(L, R, now << 1, d, flag);
 84     else if(L > mid) update(L, R, now << 1 | 1, d, flag);
 85     else update(L, mid, now << 1, d, flag), update(mid + 1, R, now << 1 | 1, d, flag);
 86     sum[now] = (sum[now << 1] + sum[now << 1 | 1]) % mod;
 87 }
 88 ll query(int L, int R, int now)
 89 {
 90     if(l[now] == L && r[now] == R) return sum[now] % mod;
 91     pushdown(now);
 92     int mid = (l[now] + r[now]) >> 1;
 93     if(R <= mid) return query(L, R, now << 1);
 94     else if(L > mid) return query(L, R, now << 1 | 1);
 95     else return (query(L, mid, now << 1) + query(mid + 1, R, now << 1 | 1)) % mod;
 96 }
 97 
 98 int main()
 99 {
100     n = read(); mod = read();
101     build(1, n, 1);
102     m = read();
103     for(int i = 1; i <= m; ++i)
104     {
105         int d = read(), L = read(), R = read();
106         if(d == 1) 
107         {
108             ll c = read();
109             update(L, R, 1, c, 0);
110         }
111         else if(d == 2)
112         {
113             ll c = read();
114             update(L, R, 1, c, 1);
115         }
116         else write(query(L, R, 1)), enter;
117     }
118     return 0;
119 }
View Code

 

以上是关于线段树2的主要内容,如果未能解决你的问题,请参考以下文章

线段树

高级数据结构线段树

数据结构线段树笔记2

线段树2

luogu3373线段树2..支持区间加值和乘值的线段树

数据结构 ---[实现 线段树(SegmentTree) ]