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
| #include <cstdio> #include <vector> #include <algorithm> #define gc (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 65536, stdin), p1 == p2) ? EOF : *p1 ++)
char buf[65536], *p1, *p2; inline int read() { char ch; int x(0); while ((ch = gc) < 48); do x = x * 10 + ch - 48; while ((ch = gc) >= 48); return x; }
const int N = 500005; inline int max(const int x, const int y) {return x > y ? x : y;}
int a[N], mem[45000005], tot, n; struct Vector { int stpos, endpos; inline void push_back(const int x) { stpos ? mem[endpos = ++ tot] = x : mem[stpos = endpos = ++ tot] = x; } inline int& operator [] (const int x) const {return mem[stpos + x];} inline int* begin() {return mem + stpos;} inline int *end() {return mem + endpos + 1;} inline int size() {return stpos ? endpos - stpos + 1 : 0;} inline bool empty() {return !stpos;} }; long long c[N]; std::vector<int> cnt[N]; bool vis[N]; inline void update(const long long x, const long long d) { for (int i(x); i <= n; i += (i & ~i + 1)) c[i] += d; } inline long long query(const int x) { long long sum(0LL); for (int i(x); i; i -= (i & ~i + 1)) sum += c[i]; return sum; }
struct Reap { Vector fac, fa; int find(const int x) {return fa[x] == x ? x : fa[x] = find(fa[x]);} inline void upd(const int l, const int r, const int x) { if (!vis[x]) { vis[x] = true; if (fac.size()) { bool flag(0); for (int i(0); i < fac.size() - 1; ++ i) if (fac[i] > fac[i + 1]) {flag = 1; break;} if (flag) std::sort(fac.begin(), fac.end()); } else return; for (int i(0); i <= fac.size(); ++ i) fa.push_back(i); } if (fac.empty()) return; int i(find(std::lower_bound(fac.begin(), fac.end(), l) - fac.begin())); while (i < fac.size() && fac[i] <= r) { if (a[fac[i]] % x) fa[i] = find(i + 1); else update(fac[i], a[fac[i]] / x - a[fac[i]]), a[fac[i]] /= x; i = find(i + 1); } } } s[N];
int main() { int m, t(0); long long last(0LL); n = read(), m = read(); for (int i(1); i <= n; ++ i) t = max(t, a[i] = read()), update(i, a[i]), cnt[a[i]].push_back(i); for (int i(2); i <= t; ++ i) for (int j(i); j <= t; j += i) for (auto k : cnt[j]) s[i].fac.push_back(k); while (m --) { int op(read()), l(read() ^ last), r(read() ^ last), x; if (op == 1) { x = read() ^ last; if (x != 1) s[x].upd(l, r, x); } else printf("%lld\n", last = query(r) - query(l - 1)); } }
|