1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
struct Node { int val; int mul; int add; explicit Node(int val=0,int mul=1,int add=0):val(val),mul(mul),add(add){} };
class Linetree { vector<Node> data; int n; const int mod=1e9+7; void init(vector<int>& nums,int l,int r,int id){ if(l>=r){ data[id].val = nums[l]; return; } int mid = (l+r)>>1; init(nums,l,mid,2*id+1); init(nums,mid+1,r,2*id+2); data[id].val = data[2*id+1].val + data[2*id+2].val; }
void update(int i,int val, int l,int r,int id){ if(l>=r) { data[id].val = val; return; } push_down(id, l, r); int mid = (l+r)>>1; if(i<=mid) update(i,val,l,mid,2*id+1); else update(i,val,mid+1,r,2*id+2); data[id].val = data[2*id+1].val + data[2*id+2].val; }
int dfs(int l,int r,int id,int ql,int qr){ if(ql<=l && r<=qr){ return data[id].val; }
push_down(id,l,r); int mid = (l+r)>>1; if(qr<=mid) return dfs(l,mid,2*id+1,ql,qr); else if(ql>mid) return dfs(mid+1,r,2*id+2,ql,qr); return dfs(l,mid,2*id+1,ql,qr) + dfs(mid+1,r,2*id+2,ql,qr); }
void push_down(int id,int l,int r){ if(data[id].mul!=1) { data[2 * id + 1].val = 1ll * data[2 * id + 1].val * data[id].mul % mod; data[2 * id + 2].val = 1ll * data[2 * id + 2].val * data[id].mul % mod; data[2 * id + 1].mul = 1ll * data[2 * id + 1].mul * data[id].mul % mod; data[2 * id + 2].mul = 1ll * data[2 * id + 2].mul * data[id].mul % mod; data[2 * id + 1].add = 1ll * data[2 * id + 1].add * data[id].mul % mod; data[2 * id + 2].add = 1ll * data[2 * id + 2].add * data[id].mul % mod; data[id].mul = 1; }
if(data[id].add!=0) { int mid = (l + r) >> 1;
data[2 * id + 1].val = (1ll * data[2 * id + 1].val + data[2 * id + 1].add * (mid - l + 1)) % mod; data[2 * id + 2].val = (1ll * data[2 * id + 2].val + data[2 * id + 2].add * (r - mid)) % mod; data[2 * id + 1].add = (data[2 * id + 1].add + data[id].add) % mod; data[2 * id + 2].add = (data[2 * id + 2].add + data[id].add) % mod;
data[id].add = 0; } }
void mul(int ml,int mr,int val, int l, int r,int id){ if(ml<=l && r<=mr){ data[id].val = 1ll * data[id].val * val % mod; data[id].mul = 1ll * data[id].mul * val % mod; data[id].add = 1ll * data[id].add * val % mod; return; }
push_down(id,l,r); int mid = (l+r)>>1; if(mr<=mid) mul(ml,mr,val,l,mid,2*id+1); else if(ml>mid) mul(ml,mr,val,mid+1,r,2*id+2); else{ mul(ml,mid,val,l,mid,2*id+1); mul(mid+1,mr,val,mid+1,r,2*id+2); } data[id].val = data[2*id+1].val + data[2*id+2].val; }
void add(int al,int ar,int val, int l, int r,int id){ if(al<=l && r<=ar){ data[id].val = (data[id].val + 1ll * val * (r-l+1)) % mod; data[id].add = (data[id].add + val) % mod; return; }
push_down(id,l,r); int mid = (l+r)>>1; if(ar<=mid) add(al,ar,val,l,mid,2*id+1); else if(al>mid) add(al,ar,val,mid+1,r,2*id+2); else{ add(al,mid,val,l,mid,2*id+1); add(mid+1,ar,val,mid+1,r,2*id+2); } data[id].val = data[2*id+1].val + data[2*id+2].val; }
public: explicit Linetree(vector<int>& nums) : data(4*nums.size()),n(nums.size()){ init(nums,0,nums.size()-1,0); }
void addAll(int l,int r,int val){ add(l,r,val,0,n-1,0); }
void mulAll(int l,int r,int val){ mul(l,r,val, 0,n-1,0); }
void update(int i,int val){ update(i, val,0, n-1,0); }
int query(int l,int r){ return dfs(0,n-1,0,l,r); } };
|