HDU 4902 line segment tree | Brute Force
Given a sequence, two operations
1: convert a segment to x.
2: convert each number in a segment into The gcd of the segment and x if it is greater than x. After the change, the final sequence is obtained.
Line Segment tree solution: use lazy to mark it. The optimization method is clever,
| Accepted |
4902 |
515 MS |
3308 K |
1941 B |
C ++ |
# Include "stdio. h "# include" string. h "struct node {int l, r, x; // represents the value on the leaf node, and the tree node represents the lazy operation of the end-to-end update .} Data [400010]; int gcd (int a, int B) {if (B = 0) return a; else return gcd (B, a % B );} void build (int l, int r, int k) {int mid; data [k]. l = l; data [k]. r = r; data [k]. x =-1; if (l = r) {scanf ("% d", & data [k]. x); return;} mid = (l + r)/2; build (l, mid, k * 2); build (mid + 1, r, k * 2 + 1);} void cover (int l, int r, int k, int x) {int mid; if (data [k]. l = l & data [k]. r = r) {data [k]. x = x; return;} mid = (data [k]. l + data [k]. r)/2; if (data [K]. x! =-1) // lazy operation {cover (data [k]. l, mid, k * 2, data [k]. x); cover (mid + 1, data [k]. r, k * 2 + 1, data [k]. x); data [k]. x =-1;} if (r <= mid) cover (l, r, k * 2, x); else if (l> mid) cover (l, r, k * 2 + 1, x); else {cover (l, mid, k * 2, x); cover (mid + 1, r, k * 2 + 1, x) ;}} void updata (int l, int r, int k, int x) {int mid; if (data [k]. x! =-1) // Optimization of operation 2 {if (data [k]. x <= x) return; // if the following end-to-end update value is less than x, 2 cover (l, r, k, gcd (data [k] is not performed. x, x); // otherwise, perform operation 2 to update the end-to-end update and return;} mid = (data [k]. l + data [k]. r)/2; if (r <= mid) updata (l, r, k * 2, x); else if (l> mid) updata (l, r, k * 2 + 1, x); else {updata (l, mid, k * 2, x); updata (mid + 1, r, k * 2 + 1, x) ;}} void pri (int k) {int I; if (data [k]. x! =-1) {for (I = data [k]. l; I <= data [k]. r; I ++) printf ("% d", data [k]. x); return;} pri (k * 2); pri (k * 2 + 1);} int main () {int Case, op, a, B, x, n, m; scanf ("% d", & Case); while (Case --) {scanf ("% d", & n); build (1, n, 1); scanf ("% d", & m); while (m --) {scanf ("% d", & op, &, & B, & x); if (op = 1) cover (a, B, 1, x); else updata (a, B, 1, x );} pri (1); printf ("\ n");} return 0 ;}
In fact, this question can also be violent, and, even faster than the line segment tree. For each node, update from the back to the back according to the operation method. If operation 1 is encountered, it will stop, otherwise, record operation 2 is followed by positive calculation of the current vertex.
| Accepted |
4902 |
250 MS |
3336 K |
754 B |
C |
# Include "stdio. h "# include" string. h "struct node {int l, r, op; _ int64 x;} mark [100010]; _ int64 a [101000], pri, B [101000]; __int64 gcd (_ int64 a ,__ int64 B) {if (B = 0) return a; return gcd (B, a % B);} int main () {int Case, n, I, j, sum, m; scanf ("% d", & Case); while (Case --) {scanf ("% d ", & n); for (I = 1; I <= n; I ++) scanf ("% I64d", & a [I]); scanf ("% d ", & m); for (I = 1; I <= m; I ++) scanf ("% d % I64d", & mark [I]. op, & mark [I]. l, & mark [I]. r, & mark [I]. x); for (I = 1; I <= n; I ++) // for each vertex, update from the back to the back by Operation {pri = a [I]; sum = 0; for (j = m; j> = 1; j --) if (mark [j]. l <= I & mark [j]. r> = I) {if (mark [j]. op = 1) // stop {pri = mark [j] In case of operation 1. x; break;} else {B [sum ++] = mark [j]. x; // records the intermediate operation 2 }}if (sum = 0) printf ("% I64d", pri); else {for (j = sum-1; j> = 0; j --) if (pri> B [j]) pri = gcd (pri, B [j]); printf ("% I64d ", pri) ;}} printf ("\ n") ;}return 0 ;}