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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| #include <bits/stdc++.h> #define re register #define ll long long
using namespace std;
mt19937 rnd(random_device{}()); const int N = 1e5 + 10,M = 5e5 + 10,K = 3e7 + 10; int n,q,rt[M]; ll lst; int num,arr[N],tmp[N]; vector<int> p[M],v[M]; bool vis[M];
inline int read(){ int r = 0; char c = getchar(); while (!isdigit(c)) c = getchar(); while (isdigit(c)){ r = (r << 3) + (r << 1) + (c ^ 48); c = getchar(); } return r; }
struct BIT{ #define lowbit(x) (x & -x)
ll tr[N];
inline void modify(int x,int k){ for (re int i = x;i <= n;i += lowbit(i)) tr[i] += k; }
inline ll query(int x){ ll res = 0; for (re int i = x;i;i -= lowbit(i)) res += tr[i]; return res; }
#undef lowbit }BT;
struct FHQ{ #define ls(u) (tr[u].l) #define rs(u) (tr[u].r)
int idx;
struct node{ int l,r,val; }tr[K];
inline int newnode(int k){ tr[++idx] = {0,0,k}; return idx; }
inline void split(int u,int k,int &x,int &y){ if (!u) return x = y = 0,void(); if (tr[u].val <= k){ x = u; split(rs(u),k,rs(u),y); } else{ y = u; split(ls(u),k,x,ls(y)); } }
inline int merge(int x,int y){ if (!x || !y) return x | y; if (rnd() < rnd()) return rs(x) = merge(rs(x),y),x; else return ls(y) = merge(x,ls(y)),y; }
inline int build(int l,int r){ if (l > r) return 0; int mid = l + r >> 1; int u = newnode(tmp[mid]); tr[u].l = build(l,mid - 1); tr[u].r = build(mid + 1,r); return u; }
inline void dfs(int u,int k){ if (ls(u)) dfs(ls(u),k); if (u == ls(u) || u == rs(u)) exit(0); if (arr[tr[u].val] % k == 0){ BT.modify(tr[u].val,-arr[tr[u].val]); BT.modify(tr[u].val,arr[tr[u].val] /= k); if (arr[tr[u].val] % k == 0) tmp[++num] = tr[u].val; } if (rs(u)) dfs(rs(u),k); }
inline void del(int l,int r,int k){ int x,y,z; split(rt[k],r,x,y); split(x,l - 1,x,z); num = 0; if (z) dfs(z,k); rt[k] = merge(merge(x,build(1,num)),y); }
#undef ls #undef rs }FT;
signed main(){ n = read(),q = read(); for (re int i = 1;i <= n;i++){ vis[arr[i] = read()] = true; BT.modify(i,arr[i]); } for (re int i = 2;i <= 5e5;i++){ for (re int j = i;j <= 5e5;j += i){ if (vis[j]) p[j].emplace_back(i); } } for (re int i = 1;i <= n;i++){ for (auto x:p[arr[i]]) v[x].emplace_back(i); } for (re int i = 2;i <= 5e5;i++){ num = 0; for (auto x:v[i]) tmp[++num] = x; rt[i] = FT.build(1,num); } while (q--){ int op,l,r; op = read(),l = read() ^ lst,r = read() ^ lst; if (op == 1){ int k; k = read() ^ lst; if (k > 1) FT.del(l,r,k); } else printf("%lld\n",lst = (BT.query(r) - BT.query(l - 1))); } return 0; }
|