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
| #include <cstdio> using namespace std; template <class Type> void read (Type &x) { char c; bool flag = false; while ((c = getchar()) < '0' || c > '9') c == '-' && (flag = true); x = c - '0'; while ((c = getchar()) >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - '0'; flag && (x = ~x + 1); } template <class Type, class ...rest> void read (Type &x, rest &...y) { read(x), read(y...); } template <class Type> void write (Type x) { x < 0 && (putchar('-'), x = ~x + 1); x > 9 && (write(x / 10), 0); putchar('0' + x % 10); } typedef long long LL; const int N = 4e5 + 10, M = 62, mod = 1e9 + 7, p[] = { 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, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293 }; int n, q, w[N], fp[N]; int binpow (int b, int k = mod - 2) { int res = 1; for (; k; k >>= 1, b = (LL)b * b % mod) if (k & 1) res = (LL)res * b % mod; return res; } struct Data { LL s; int t; Data (LL _s = 0, int _t = 1) { s = _s, t = _t; } Data operator + (const Data &_) const { Data res = *this; return res += _; } Data& operator += (const Data &_) { s |= _.s, t = (LL)t * _.t % mod; return *this; } Data operator ^ (const int &k) const { Data res = *this; return res ^= k; } Data& operator ^= (const int &k) { t = binpow(t, k); return *this; } }; struct Node { Data s, t; int l, r; } tr[N << 2]; LL calc (int x) { LL res = 0; for (int i = 0; i < M; ++i) if (x % p[i] == 0) res |= 1ll << i; return res; } void add (int x, Data t) { tr[x].s += t ^ tr[x].r - tr[x].l + 1, tr[x].t += t; } void pushdown (int x) { add(x << 1, tr[x].t), add(x << 1 | 1, tr[x].t); tr[x].t = Data(); } void build (int l = 1, int r = n, int x = 1) { tr[x].l = l, tr[x].r = r; if (l == r) return void(tr[x].s = Data(calc(w[l]), w[l])); int mid = l + r >> 1; build(l, mid, x << 1), build(mid + 1, r, x << 1 | 1); tr[x].s = tr[x << 1].s + tr[x << 1 | 1].s; } void modify (int l, int r, Data k, int x = 1) { if (tr[x].l >= l && tr[x].r <= r) return add(x, k); pushdown(x); int mid = tr[x].l + tr[x].r >> 1; if (l <= mid) modify(l, r, k, x << 1); if (r > mid) modify(l, r, k, x << 1 | 1); tr[x].s = tr[x << 1].s + tr[x << 1 | 1].s; } Data query (int l, int r, int x = 1) { if (tr[x].l >= l && tr[x].r <= r) return tr[x].s; pushdown(x); int mid = tr[x].l + tr[x].r >> 1; if (r <= mid) return query(l, r, x << 1); if (l > mid) return query(l, r, x << 1 | 1); return query(l, r, x << 1) + query(l, r, x << 1 | 1); } int main () { for (int i = 0; i < M; ++i) fp[i] = (p[i] - 1ll) * binpow(p[i]) % mod; read(n, q); for (int i = 1; i <= n; ++i) read(w[i]); build(); for (char op[10]; q; --q) { scanf("%s", op); if (op[0] == 'M') { int l, r, x; read(l, r, x); modify(l, r, Data(calc(x), x)); } else if (op[0] == 'T') { int l, r; read(l, r); Data k = query(l, r); for (int i = 0; i < M; ++i) if (k.s >> i & 1) k.t = (LL)k.t * fp[i] % mod; write((k. t + mod) % mod), puts(""); } } return 0; }
|