给定两个操作:
MULTIPLY L R x 区间里都乘以一个数x
MAX L R : 计算区间内一个2,3,5,7个数最大值。
思路:维护4个最大值。蓝瘦。
1 /** 有 n 个数和 5 种操作 2 add a b c:把区间[a,b]内的所有数都增加 c 3 set a b c:把区间[a,b]内的所有数都设为 c 4 sum a b:查询区间[a,b]的区间和 5 max a b:查询区间[a,b]的最大值 6 min a b:查询区间[a,b]的最小值 7 */ 8 #include <bits/stdc++.h> 9 using namespace std; 10 const int maxn = 2e5 + 7; 11 const long long INF = 1LL << 62; 12 int Pri[]={ 2 , 3 , 5 , 7 }; 13 struct Segment_tree 14 { 15 struct Node 16 { 17 int l, r; 18 long long sum, max, min, set_lazy, add_lazy; 19 } tre[maxn << 2]; 20 long long arr[maxn*4];//需要输入的数组 21 inline void push_up(int rt) 22 { 23 if(tre[rt].l == tre[rt].r) 24 { 25 return ; 26 } 27 tre[rt].sum = tre[rt<<1].sum + tre[rt<<1|1].sum; 28 tre[rt].max = max(tre[rt<<1].max, tre[rt<<1|1].max); 29 tre[rt].min = min(tre[rt<<1].min, tre[rt<<1|1].min); 30 } 31 inline void push_down(int rt) 32 { 33 if(tre[rt].set_lazy) { 34 ///if set_lazy add_lazy = 0 35 tre[rt<<1].set_lazy = tre[rt].set_lazy; 36 tre[rt<<1].sum = (tre[rt<<1].r - tre[rt<<1].l + 1) * tre[rt].set_lazy; 37 tre[rt<<1].max = tre[rt].set_lazy; 38 tre[rt<<1].min = tre[rt].set_lazy; 39 tre[rt<<1|1].set_lazy = tre[rt].set_lazy; 40 tre[rt<<1|1].sum = (tre[rt<<1|1].r - tre[rt<<1|1].l + 1) * tre[rt].set_lazy; 41 tre[rt<<1|1].max = tre[rt].set_lazy; 42 tre[rt<<1|1].min = tre[rt].set_lazy; 43 tre[rt].add_lazy = 0; 44 tre[rt<<1].add_lazy = tre[rt<<1|1].add_lazy = 0; 45 tre[rt].set_lazy = 0; 46 return ; 47 } 48 if(tre[rt].add_lazy) 49 { 50 tre[rt<<1].add_lazy += tre[rt].add_lazy; 51 tre[rt<<1].sum += (tre[rt<<1].r - tre[rt<<1].l + 1) * tre[rt].add_lazy; 52 tre[rt<<1].max += tre[rt].add_lazy; 53 tre[rt<<1].min += tre[rt].add_lazy; 54 tre[rt<<1|1].add_lazy += tre[rt].add_lazy; 55 tre[rt<<1|1].sum += (tre[rt<<1|1].r - tre[rt<<1|1].l + 1) * 56 tre[rt].add_lazy; 57 tre[rt<<1|1].max += tre[rt].add_lazy; 58 tre[rt<<1|1].min += tre[rt].add_lazy; 59 tre[rt].add_lazy = 0; 60 } 61 } 62 void build(int rt,int l,int r) 63 { 64 tre[rt].l = l; 65 tre[rt].r = r; 66 tre[rt].set_lazy = 0; 67 tre[rt].add_lazy = 0; 68 if(l == r) 69 { 70 tre[rt].sum = tre[rt].max = tre[rt].min = arr[l]; 71 return ; 72 } 73 int mid = (l + r) >> 1; 74 build(rt<<1,l,mid); 75 build(rt<<1|1,mid+1,r); 76 push_up(rt); 77 } 78 void update1(int rt,int l,int r,long long val)///add 79 { 80 push_down(rt); 81 if(l == tre[rt].l && tre[rt].r == r) 82 { 83 tre[rt].add_lazy = val; 84 tre[rt].sum += (tre[rt].r - tre[rt].l + 1) * val; 85 tre[rt].max += val; 86 tre[rt].min += val; 87 return ; 88 } 89 int mid = (tre[rt].l + tre[rt].r) >> 1; 90 if(r <= mid) 91 { 92 update1(rt<<1,l,r,val); 93 } 94 else if(l > mid) 95 { 96 update1(rt<<1|1,l,r,val); 97 } 98 else 99 { 100 update1(rt<<1,l,mid,val); 101 update1(rt<<1|1,mid+1,r,val); 102 } 103 push_up(rt); 104 } 105 void update2(int rt,int l,int r,long long val)///set 106 { 107 push_down(rt); 108 if(l == tre[rt].l && tre[rt].r == r) { 109 tre[rt].set_lazy = val; 110 tre[rt].sum = (tre[rt].r - tre[rt].l + 1) * val; 111 tre[rt].max = val; 112 tre[rt].min = val; 113 tre[rt].add_lazy = 0; 114 return ; 115 } 116 int mid = (tre[rt].l + tre[rt].r) >> 1; 117 if(r <= mid) { 118 update2(rt<<1,l,r,val); 119 } else if(l > mid) { 120 update2(rt<<1|1,l,r,val); 121 } else { 122 update2(rt<<1,l,mid,val); 123 update2(rt<<1|1,mid+1,r,val); 124 } 125 push_up(rt); 126 } 127 long long query1(int rt,int l,int r)///sum 128 { 129 push_down(rt); 130 if(l == tre[rt].l && tre[rt].r == r) { 131 return tre[rt].sum; 132 } 133 int mid = (tre[rt].l + tre[rt].r) >> 1; 134 if(r <= mid) { 135 return query1(rt<<1,l,r); 136 } else if(l > mid) { 137 return query1(rt<<1|1,l,r); 138 } else { 139 return query1(rt<<1,l,mid) + query1(rt<<1|1,mid+1,r); 140 } 141 } 142 long long query2(int rt,int l,int r)///max 143 { 144 push_down(rt); 145 if(l == tre[rt].l && tre[rt].r == r) { 146 return tre[rt].max; 147 } 148 int mid = (tre[rt].l + tre[rt].r) >> 1; 149 if(r <= mid) { 150 return query2(rt<<1,l,r); 151 } else if(l > mid) { 152 return query2(rt<<1|1,l,r); 153 } else { 154 return max(query2(rt<<1,l,mid), query2(rt<<1|1,mid+1,r)); 155 } 156 } 157 long long query3(int rt,int l,int r)///min 158 { 159 push_down(rt); 160 if(l == tre[rt].l && tre[rt].r == r) { 161 return tre[rt].min; 162 } 163 int mid = (tre[rt].l + tre[rt].r) >> 1; 164 if(r <= mid) { 165 return query3(rt<<1,l,r); 166 } else if(l > mid) { 167 return query3(rt<<1|1,l,r); 168 } else { 169 return min(query3(rt<<1,l,mid), query3(rt<<1|1,mid+1,r)); 170 } 171 } 172 }st[10]; 173 int main(){ 174 int n,m; 175 scanf("%d%d",&n,&m); 176 for(int i=0;i<4;i++) 177 st[i].build(1,1,n); 178 while(m--){ 179 char Q[20]; 180 scanf("%s",Q); 181 int L,R; 182 if(Q[1]=='U'){ 183 int x; 184 scanf("%d%d%d",&L,&R,&x); 185 for(int i=0;i<4;i++){ 186 if(x%Pri[i]==0){ 187 while(x%Pri[i]==0){ 188 st[i].update1(1,L,R,1); 189 x/=Pri[i]; 190 } 191 } 192 } 193 }else{ 194 scanf("%d%d",&L,&R); 195 long long int ans=0; 196 for(int i=0;i<4;i++){ 197 ans=max(ans,st[i].query2(1,L,R)); 198 } 199 printf("ANSWER "); 200 printf("%lld ",ans); 201 } 202 } 203 return 0; 204 } 205 206 /* 207 5 6 208 MULTIPLY 3 5 2 209 MULTIPLY 2 5 3 210 211 MAX 1 5 212 MULTIPLY 1 4 2 213 MULTIPLY 2 5 5 214 MAX 3 5 215 216 */