线段树很长时间没有写了。。。于是蒟蒻竟然不会了。。。

这棵线段树要维护两个lazy tag:

1、乘的倍数

2、加的数字

每次更新的时候都要注意运算符优先级就可以了。

 

  1 /**************************************************************
  2     Problem: 1798
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:3896 ms
  7     Memory:10184 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <algorithm>
 12  
 13 using namespace std;
 14 typedef long long ll;
 15  
 16 struct sgement_tree{
 17     ll sum, mul, add;
 18 }seg[400025];
 19 ll mod;
 20 int n, M, L, R, X, oper, Mul, Add;
 21  
 22 inline ll read(){
 23     ll x = 0;
 24     char ch = getchar();
 25     while (ch < '0' || ch > '9')
 26         ch = getchar();
 27          
 28     while (ch >= '0' && ch <= '9'){
 29         x = x * 10 + ch - '0';
 30         ch = getchar();
 31     }
 32     return x;
 33 }
 34  
 35 inline void refresh(int p, int D){
 36     int l = p << 1, r = p << 1 | 1;
 37     seg[l].sum = (seg[l].sum * seg[p].mul + (D - (D >> 1)) * seg[p].add) % mod;
 38     seg[l].mul = seg[l].mul * seg[p].mul % mod;
 39     seg[l].add = (seg[l].add * seg[p].mul + seg[p].add) % mod;
 40     seg[r].sum = (seg[r].sum * seg[p].mul + (D >> 1) * seg[p].add) % mod;
 41     seg[r].mul = seg[r].mul * seg[p].mul % mod;
 42     seg[r].add = (seg[r].add * seg[p].mul + seg[p].add) % mod;
 43     seg[p].mul = 1, seg[p].add = 0;
 44 }
 45  
 46 inline void fresh(int p){
 47     seg[p].sum = (seg[p << 1].sum + seg[p << 1 | 1].sum) % mod;
 48 }
 49  
 50 void build_seg(int p, int l, int r){
 51     seg[p].mul = 1, seg[p].add = 0;
 52     if (l == r){
 53         seg[p].sum = read();
 54         return;
 55     }
 56     int mid = (l + r) >> 1;
 57     build_seg(p << 1, l, mid);
 58     build_seg(p << 1 | 1, mid + 1, r);
 59     fresh(p);
 60 }
 61  
 62 void update(int p, int l, int r){
 63     if (R < l || r < L) return;
 64     if (L <= l && r <= R){
 65         seg[p].sum = (seg[p].sum * Mul + (r - l + 1) * Add) % mod;
 66         seg[p].mul = seg[p].mul * Mul % mod;
 67         seg[p].add = (seg[p].add * Mul + Add) % mod;
 68         return;
 69     }
 70     int mid = (l + r) >> 1;
 71     refresh(p, r - l + 1);
 72     update(p << 1, l, mid);
 73     update(p << 1 | 1, mid + 1, r);
 74     fresh(p);
 75 }
 76  
 77 ll query(int p, int l, int r){
 78     if (R < l || r < L) return 0;
 79     if (L <= l && r <= R) return seg[p].sum;
 80     int mid = (l + r) >> 1;
 81     refresh(p, r - l + 1);
 82     ll res = (query(p << 1, l, mid) + query(p << 1 | 1, mid + 1, r)) % mod;
 83     fresh(p);
 84     return res;
 85 }
 86  
 87 int main(){
 88     n = read(), mod = read();
 89     build_seg(1, 1, n);
 90     M = read();
 91     while (M--){
 92         oper = read();
 93         if (oper == 1){
 94             L = read(), R = read();
 95             Mul = read(), Add = 0;
 96             update(1, 1, n);
 97         }else
 98         if (oper == 2){
 99             L = read(), R = read();
100             Mul = 1, Add = read();
101             update(1, 1, n);
102         }else{
103             L = read(), R = read();
104             printf("%lld\n", query(1, 1, n));
105         }
106     }
107     return 0;
108 }
View Code

 

posted on 2014-10-25 20:18  Xs酱~  阅读(1309)  评论(2编辑  收藏  举报