I, entitled
Second, analysis
A very good question.
First, consider the relatively violent approach, certainly Yaoan range for processing, for $ lcm $ and $ gcd $ can be evaluated using the standard formula, but when seeking $ lcm $ is sure to burst the $ long long $.
Consider prime decomposition, after all the factorization, found limited number of prime factors, each factor and the power is limited, i.e. up to $ 2 ^ _6 $, then the prime factors may be considered in every binary It is expressed. For $ 2,3,5,7 $ might want more, so give it to a few, and finally found, just to within $ 32 $ bit.
Here it is necessary to write two conversion functions, then using the properties of $ gcd $ and $ lcm $ is solved and transformation. Finally, consider the range query and modify a single point, and then a segment tree can be.
Three, AC codes
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <cmath> using namespace std; #define ll long long #define Min(a,b) ((a)>(b)?(b):(a)) #define Max(a,b) ((a)>(b)?(a):(b)) #define lson (rt<<1) #define rson (rt<<1|1) const int MAXN = 1e5; struct Node { int L, G; }segTree[MAXN<<2]; int Prime[25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97}; int Pos[25] = {28,25 , 23 , 21 , 20 , 19 , 18 , 17 , 16 , 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 }; inline 're GCD ( you get, you y) { //Finally, phase &, if it continues with Min, the equivalent of only one lead WA return Min (the X-& 0x70000000 , the y-& 0x70000000 ) | Min (the X-& 0x0e000000 , the y-& 0x0e000000 ) | Min (the X-& 0x01800000 , the y-& 0x01800000 ) | Min (the X-& 0x00600000 , Y & 0x00600000 ) | ((X & 0x001FFFFF ) & (Y & 0x001FFFFF )); } inline int of Lcm ( int X, int Y) { return Max (X & 0x70000000 , Y & 0x70000000 ) | Max (X & 0x0e000000 , Y & 0x0e000000) | Max (x & 0x01800000 , Y & 0x01800000 ) | Max (x & 0x00600000 , Y & 0x00600000 ) | ((x & 0x001FFFFF ) | (Y & 0x001FFFFF )); } // x-quality factorization, and is expressed in binary inline int Turn ( int x ) { int RES, ANS = 0 ; for ( int I = 0 ; I < 25 && X> . 1 ; I ++ ) { RES = 0 ; the while (X% Prime [I] == 0 ) { RES++; x/=Prime[i]; } ans |= (res<<Pos[i]); } return ans; } int Mi2[] = {1, 2, 4, 8, 16, 32, 64}; int Mi3[] = {1, 3, 9, 27, 81}; int Mi5[] = {1, 5, 25}; int Mi7[] = {. 1 , . 7 , 49 }; // the number of binary representation of the number of original and changed around modulo inline int the Get ( int X, int P) { LL ANS = . 1 ; int RES >> Pos X = [ 0 ]; X ^ = RES << Pos [ 0 ]; // erase the bits represents a number of 2 ANS = ANS * Mi2 [RES]% P; // exponential 3 and erasing RES >> Pos X = [ . 1 ]; ^ = X << RES Pos [ . 1 ]; * ANS ANS = Mi3 [RES]% P; // exponential 5 and erasing res = x >> Pos [ 2]; x ^= res<<Pos[2]; ans = ans * Mi5[res] % p; //求7的指数并消去 res = x>>Pos[3]; x ^= res<<Pos[3]; ans = ans * Mi7[res] % p; for(int i = 4; i < 25; i++) { if((x>>Pos[i])&1) { ans = ans * Prime[i] % p; } } return ans % p; } void Push_up(int rt) { segTree[rt].G = Gcd(segTree[lson].G, segTree[rson].G); segTree[rt].L = Lcm(segTree[lson].L, segTree[rson].L); return; } void Build(int rt, int l, int r) { if(l == r) { int a; scanf("%d", &a); segTree[rt].G = Turn(a); segTree[rt].L = Turn(a); return; } int mid = (l + r) >> 1; Build(lson, l, mid); Build(rson, mid + 1, r); Push_up(rt); } void Change(int rt, int l, int r, int pos, int val) { if(l == r) { segTree[rt].G = Turn(val); segTree[rt].L = segTree[rt].G; return; } int mid = (l + r) >> 1; if(pos <= mid) { Change(lson, l, mid, pos, val); } else if (pos > mid) { Change(rson, mid + 1, r, pos, val); } Push_up(rt); } int anslcm, ansgcd; void Query_lcm(int rt, int l, int r, int L, int R) { if(L <= l && r <= R) { anslcm = Lcm(anslcm, segTree[rt].L); return; } int mid = (l + r) >> 1; if(L <= mid) { Query_lcm(lson, l, mid, L, R); } if(R > mid) { Query_lcm(rson, mid + 1, r, L, R); } } void Query_gcd(int rt, int l, int r, int L, int R) { if(L <= l && r <= R) { ansgcd = Gcd(ansgcd, segTree[rt].G); return; } int mid = (l + r) >> 1; if(L <= mid) { Query_gcd(lson, l, mid, L, R); } if(R > mid) { Query_gcd(rson, mid + 1, r, L, R); } } int main() { //freopen("input.txt", "r", stdin); int N, Q; while(scanf("%d%d", &N, &Q) != EOF) { Build(1, 1, N); char s[2]; for(int i = 0; i < Q; i++) { scanf("%s", s); int a, b, c; if(s[0] == 'L') { anslcm = 0; scanf("%d%d%d", &a, &b, &c); Query_lcm(1, 1, N, a, b); int ans = Get(anslcm, c); printf("%d\n", ans); } else if(s[0] == 'G') { ansgcd = 0x7fffffff; scanf("%d%d%d", &a, &b, &c); Query_gcd(1, 1, N, a, b); int ans = Get(ansgcd, c); printf("%d\n", ans); } else { scanf("%d%d", &a, &c); Change(1, 1, N, a, c); } } } return 0; }