For a sequence of numbers, the first operation is to assign all the numbers in [L, R] to X, and the second operation is to [L, r] The number larger than X is assigned to the GCD of the number and X, and the entire sequence is output after several operations.
Solution: the most important thing to maintain in the line segment tree is whether all numbers in a range are equal. Only maintenance of this item can be done. I wanted to maintain MAX [RT], which indicates the maximum value of the segment. If the maximum value is <= x, no updates are required, however, it seems that the "optimization" operation is slower.
I think it is probably because if the maximum values of the two Subtrees or the number of the two Subtrees are not completely equal, you cannot directly upload this value or the next GCD, because you do not know which value to update. Therefore, we need to maintain a flag with equal intervals. In this case, it is also updated to the leaf node, which is exactly what we want to update.
As long as you understand what you want to maintain, it is not difficult for the rest.
Code 1: (add a max tag)
# Include <iostream> # include <cstdio> # include <cstring> # include <cstdlib> # include <cmath> # include <algorithm> using namespace STD; # define n Limit 7int MAX [4 * n], Mark [4 * n]; // mark [RT] =-1 indicates that the value of this segment is inconsistent, otherwise, Mark [RT] is equal to the unified int gcd (int A, int B) {If (! B) return a; return gcd (B, A % B);} void pushup (INT RT) {max [RT] = max (MAX [2 * RT], max [2 * RT + 1]);} void Pushdown (int l, int R, int RT) {If (MARK [RT]! =-1) // This segment has the same value {mark [2 * RT] = mark [2 * RT + 1] = mark [RT]; max [2 * RT] = MAX [2 * RT + 1] = MAX [RT]; Mark [RT] =-1 ;}} void build (int l, int R, int RT) {mark [RT] =-1; if (L = r) {scanf ("% d", & MAX [RT]); mark [RT] = MAX [RT]; return;} int mid = (L + r)/2; build (L, mid, 2 * RT ); build (Mid + 1, R, 2 * RT + 1); pushup (RT);} void Update (int l, int R, int AA, int BB, int Val, int tag, int RT) {If (AA <= L & BB> = r) {If (TAG = 1) {max [RT] = Mark [RT] = val; return;} else {If (MARK [RT]! =-1) // This segment value is equal {If (MAX [RT]> Val) // to update MAX [RT] = mark [RT] = gcd (MARK [RT], val); Return ;}} Pushdown (L, R, RT); int mid = (L + r)/2; If (AA <= mid) Update (L, mid, AA, BB, Val, Tag, 2 * RT); If (BB> mid) Update (Mid + 1, R, AA, BB, Val, tag, 2 * RT + 1); pushup (RT);} void print (int l, int R, int RT) {If (L = r) {printf ("% d", Max [RT]); return;} Pushdown (L, R, RT); int mid = (L + r)/2; print (L, mid, 2 * RT); print (Mid + 1, R, 2 * RT + 1);} int main () {int n, m, I, t, Tag, AA, BB, Val; scanf ("% d", & T); While (t --) {scanf ("% d", & N ); build (1, n, 1); scanf ("% d", & M); While (M --) {scanf ("% d ", & tag, & aa, & BB, & Val); Update (1, n, AA, BB, Val, Tag, 1);} print (1, n, 1 ); puts ("");} return 0 ;}
View code
Code 2: (maintain only one)
# Include <iostream> # include <cstdio> # include <cstring> # include <cstdlib> # include <cmath> # include <algorithm> using namespace STD; # define n Limit 7int MAX [4 * n]; int gcd (int A, int B) {If (! B) return a; return gcd (B, A % B);} void pushup (INT RT) {If (MAX [2 * RT] = MAX [2 * RT + 1]) Max [RT] = MAX [2 * RT];} void Pushdown (INT l, int R, int RT) {If (MAX [RT]! =-1) Max [2 * RT] = MAX [2 * RT + 1] = MAX [RT], Max [RT] =-1;} void build (INT l, int R, int RT) {max [RT] =-1; if (L = r) {scanf ("% d", & MAX [RT]); return ;} int mid = (L + r)/2; build (L, mid, 2 * RT); Build (Mid + 1, R, 2 * RT + 1 ); pushup (RT);} void Update (int l, int R, int AA, int BB, int Val, int tag, int RT) {If (AA <= L & BB> = r) {If (TAG = 1) {max [RT] = val; return ;} else {If (MAX [RT]! =-1) {If (MAX [RT]> Val) // The value below is greater than that of the value below, that is, Max [RT] = gcd (MAX [RT], val); Return ;}} Pushdown (L, R, RT); int mid = (L + r)/2; If (AA <= mid) Update (L, mid, AA, BB, Val, Tag, 2 * RT); If (BB> mid) Update (Mid + 1, R, AA, BB, Val, tag, 2 * RT + 1); pushup (RT);} void print (int l, int R, int RT) {If (L = r) {printf ("% d", Max [RT]); return;} Pushdown (L, R, RT); int mid = (L + r)/2; print (L, mid, 2 * RT); print (Mid + 1, R, 2 * RT + 1);} int main () {int n, m, I, t, Tag, AA, BB, Val; scanf ("% d", & T); While (t --) {scanf ("% d", & N ); build (1, n, 1); scanf ("% d", & M); While (M --) {scanf ("% d ", & tag, & aa, & BB, & Val); Update (1, n, AA, BB, Val, Tag, 1);} print (1, n, 1 ); puts ("");} return 0 ;}
View code
HDU 4902 nice boat -- Line Segment tree (Interval Update)