1+ /* *
2+ * @file 6952.cpp
3+ * @author Macesuted ([email protected] ) 4+ * @date 2024-12-15
5+ *
6+ * @copyright Copyright (c) 2024
7+ *
8+ */
9+
10+ #include < bits/stdc++.h>
11+ using namespace std ;
12+
13+ #ifndef LOCAL
14+ #define endl ' \n '
15+ #endif
16+
17+ namespace IO {
18+ const int SIZE = 1 << 20 ;
19+ char Ibuf[SIZE], *Il = Ibuf, *Ir = Ibuf, Obuf[SIZE], *Ol = Obuf, *Or = Ol + SIZE - 1 ;
20+ int cache[100 ];
21+ void fill (void ) { return Ir = (Il = Ibuf) + fread (Ibuf, 1 , SIZE, stdin), void (); }
22+ void flush (void ) { return fwrite (Obuf, 1 , Ol - Obuf, stdout), Ol = Obuf, void (); }
23+ char getch (void ) { return Il == Ir ? fill (), Il == Ir ? EOF : *Il++ : *Il++; }
24+ void putch (char x) { return *Ol++ = x, Ol == Or && (flush (), 0 ), void (); }
25+ template <typename T = int >
26+ T read (void ) {
27+ T x = 0 , f = +1 ;
28+ char c = getch ();
29+ while (c < ' 0' || c > ' 9' ) (c == ' -' ) && (f = -f), c = getch ();
30+ while (' 0' <= c && c <= ' 9' ) x = (x << 3 ) + (x << 1 ) + (c ^ 48 ), c = getch ();
31+ return x * f;
32+ }
33+ template <typename T>
34+ void write (T x) {
35+ if (!x) return putch (' 0' );
36+ if (x < 0 ) putch (' -' ), x = -x;
37+ int top = 0 ;
38+ while (x) cache[top++] = x % 10 , x /= 10 ;
39+ while (top) putch (cache[--top] ^ 48 );
40+ return ;
41+ }
42+ struct Flusher_ {
43+ ~Flusher_ () { flush (); }
44+ } io_flusher_;
45+ } // namespace IO
46+ using IO::putch;
47+ using IO::read;
48+ using IO::write;
49+
50+ bool mem1;
51+
52+ #define maxn 250005
53+ #define maxsqrtn 600
54+ #define mod 998244353
55+
56+ typedef pair<int , int > pii;
57+
58+ bool notp[maxn];
59+ vector<int > prime;
60+ set<int > S[maxn];
61+ int64_t a[maxn], mul[maxsqrtn], f[maxn], nxt[maxn];
62+ int xv[maxn], bl[maxsqrtn], br[maxsqrtn], bel[maxn], rest[maxn], jmp[maxn];
63+ bool vis[maxsqrtn];
64+
65+ int64_t Mod (int64_t x) { return x >= mod ? x - mod : x; }
66+
67+ vector<int > split (int v) {
68+ vector<int > ans;
69+ while (v != 1 ) ans.push_back (xv[v]), v /= xv[v];
70+ return ans;
71+ }
72+
73+ void build (int id) {
74+ for (int i = br[id]; i >= bl[id]; i--) {
75+ f[i] = a[i], nxt[i] = i + jmp[i];
76+ if (nxt[i] <= br[id]) f[i] = Mod (f[i] + f[nxt[i]]), nxt[i] = nxt[nxt[i]];
77+ }
78+ return ;
79+ }
80+
81+ void solve (void ) {
82+ int n = read (), q = read ();
83+ for (int i = 1 ; i <= n; i++) {
84+ a[i] = read (), rest[i] = i / (jmp[i] = __gcd ((int64_t )i, a[i]));
85+ auto ret = split (rest[i]);
86+ for (auto v : ret) S[v].insert (i);
87+ }
88+
89+ int Bsiz = sqrt (n), Bcnt = 0 ;
90+ while (br[Bcnt] < n) Bcnt++, bl[Bcnt] = br[Bcnt - 1 ] + 1 , br[Bcnt] = min (br[Bcnt - 1 ] + Bsiz, n), mul[Bcnt] = 1 ;
91+
92+ for (int t = 1 ; t <= Bcnt; t++)
93+ for (int i = bl[t]; i <= br[t]; i++) bel[i] = t;
94+
95+ for (int t = 1 ; t <= Bcnt; t++) build (t);
96+
97+ while (q--) {
98+ int op = read ();
99+ if (op == 1 ) {
100+ int l = read (), r = read (), x = read ();
101+ vector<int > rec;
102+
103+ rec.push_back (bel[l]), rec.push_back (bel[r]);
104+
105+ if (bel[l] == bel[r])
106+ for (int i = l; i <= r; i++) a[i] = a[i] * x % mod;
107+ else {
108+ for (int i = l; i <= br[bel[l]]; i++) a[i] = a[i] * x % mod;
109+ for (int i = bl[bel[r]]; i <= r; i++) a[i] = a[i] * x % mod;
110+ for (int i = bel[l] + 1 ; i < bel[r]; i++) mul[i] = mul[i] * x % mod;
111+ }
112+
113+ vector<int > ret = split (x);
114+ for (auto v : ret)
115+ for (auto p = S[v].lower_bound (l); p != S[v].end () && *p <= r;) {
116+ rec.push_back (bel[*p]), rest[*p] /= v, jmp[*p] *= v;
117+ if (rest[*p] % v)
118+ p = S[v].erase (p);
119+ else
120+ p++;
121+ }
122+
123+ for (auto id : rec)
124+ if (!vis[id]) vis[id] = true , build (id);
125+ for (auto id : rec) vis[id] = false ;
126+ } else {
127+ int x = read ();
128+ int64_t ans = 0 ;
129+ while (x <= n) ans = (ans + f[x] * mul[bel[x]]) % mod, x = nxt[x];
130+ write (ans), putch (' \n ' );
131+ }
132+ }
133+
134+ return ;
135+ }
136+
137+ bool mem2;
138+
139+ int main () {
140+ ios::sync_with_stdio (false ), cin.tie (nullptr );
141+ #ifdef LOCAL
142+ cerr << " Memory Cost: " << abs (&mem1 - &mem2) / 1024 . / 1024 . << " MB" << endl;
143+ #endif
144+
145+ for (int i = 2 ; i < maxn; i++) {
146+ if (!notp[i]) prime.push_back (i), xv[i] = i;
147+ for (auto j = prime.begin (); i * *j < maxn; j++) {
148+ notp[i * *j] = true , xv[i * *j] = *j;
149+ if (i % *j == 0 ) break ;
150+ }
151+ }
152+
153+ int _ = 1 ;
154+ while (_--) solve ();
155+
156+ #ifdef LOCAL
157+ cerr << " Time Cost: " << clock () * 1000 . / CLOCKS_PER_SEC << " MS" << endl;
158+ #endif
159+ return 0 ;
160+ }
0 commit comments