洛谷P3373 【模板】线段树2

1. 加法和乘法顺序不一样会导致不同的结果

(1) 先加后乘 : (a+b)*c = a*c + b*c

(2) 先乘后加：a*c + b

ls           rs

然后加入C和B是父亲的懒标记，那么按照先乘后加应该这么算：(a*c+b)*C+B

化简：  =  　a*c*C+b*C+B

=    a*(c*C) + (b*C+B)

  1 #include<cstdio>
2 #include<iostream>
3
4 #define LL long long int
5 #define ls o<<1
6 #define rs o<<1|1
7 #define M ((L+R)>>1)
8
9 using namespace std;
10 const int maxn = 100010;
11
12 LL n, m, p;
13 LL A[maxn], sumv[maxn*4], addv[maxn*4], mulv[maxn*4];
14
15 LL add(LL a,LL b) {//方便取模
16     return (a+b)%p;
17 }
18
19 LL mul(LL a,LL b) {
20     return (a*b)%p;
21 }
22
23 inline void build(LL o,LL L,LL R) {
24     mulv[o] = 1;
25     if(L == R) sumv[o] = A[L] % p;
26     else {
27         build(ls,L,M);
28         build(rs,M+1,R);
30     }
31 }
32
33 inline void pushdown(LL o,LL L,LL R) {//划重点
34     sumv[ls] = mul(sumv[ls],mulv[o]);
35     sumv[rs] = mul(sumv[rs],mulv[o]);
38
39     mulv[ls] = mul(mulv[ls],mulv[o]);
40     mulv[rs] = mul(mulv[rs],mulv[o]);
45
47     mulv[o] = 1;
48 }
49
50 LL ql,qr,qa,qm;
51 inline void updatea(LL o,LL L,LL R) {
52     if(ql <= L &&  R <= qr) {
55         return;
56     }
57     pushdown(o,L,R);
58     if(ql <= M) updatea(ls,L,M);
59     if(qr > M) updatea(rs,M+1,R);
61 }
62
63 inline void updatem(LL o,LL L,LL R) {
64   if(ql <= L && R <= qr) {
65       mulv[o] = mul(mulv[o],qm);
67       sumv[o] = mul(sumv[o],qm);
68       return;
69     }
70     pushdown(o,L,R);
71     if(ql <= M) updatem(ls,L,M);
72     if(qr > M) updatem(rs,M+1,R);
74 }
75
76 inline LL query(LL o,LL L,LL R) {
77     if(ql <= L && R <= qr) return sumv[o];
78     pushdown(o,L,R);
79     LL ret = 0;
80     if(ql <= M) ret = add(ret, query(ls,L,M));
81     if(qr > M) ret = add(ret, query(rs,M+1,R));
82     return ret%p;
83 }
84
85 int main() {
86     cin >> n >> m >> p;
87     for(int i = 1;i <= n;i++) scanf("%lld",&A[i]);
88
89     build(1,1,n);
90
91     for(int i = 1,x;i <= m;i++) {
92         scanf("%d",&x);
93         if(x == 1) {
94             scanf("%lld%lld%lld",&ql,&qr,&qm);
95             updatem(1,1,n);
96         } else if(x == 2) {
97             scanf("%lld%lld%lld",&ql,&qr,&qa);
98             updatea(1,1,n);
99         } else {
100             scanf("%lld%lld",&ql,&qr);
101             printf("%lld\n", query(1,1,n));
102         }
103     }
104
105     return 0;
106 } 

posted @ 2018-08-22 21:22  Frank的成长之路  阅读(220)  评论(0编辑  收藏  举报