Author : Dipu Kumar Mohanto
CSE, Batch - 6
BRUR.
Problem Statement : DIVMAC - Dividing Machine
Source : Codechef
Category : Number Theory, Data Structure
Algorithm : Sieve - Smallest Prime Factor, Segment Tree
Verdict : Accepted
- #include "bits/stdc++.h"
-
- using namespace std;
-
- #define ll long long int
- #define endl '\n'
-
- static const int maxn = 2e6 + 5;
-
- bool isprime[maxn];
- vector <int> prime;
- int sp[maxn];
-
- void sieve()
- {
- for (int i = 2; i < maxn; i++) isprime[i] = true;
- sp[2] = 2;
- for (int i = 4; i < maxn; i += 2) isprime[i] = false, sp[i] = 2;
- for (long long i = 3; i < maxn; i += 2)
- {
- if (isprime[i])
- {
- sp[i] = i;
- for (long long j = i; i * j < maxn; j += 2)
- {
- if (isprime[i * j])
- {
- isprime[i * j] = false;
- sp[i * j] = i;
- }
- }
- }
- }
- prime.push_back(2);
- for (int i = 3; i < maxn; i += 2) if (isprime[i]) prime.push_back(i);
- }
-
- struct SegmentTree
- {
- int num;
- int lpf;
- SegmentTree(int num = 0, int lpf = 0) : num(num), lpf(lpf) {}
-
- void assignLeaf(int x, int y)
- {
- num = x;
- lpf = y;
- }
- void marge(const SegmentTree &lchild, const SegmentTree &rchild)
- {
- num = max(lchild.num, rchild.num);
- lpf = max(lchild.lpf, rchild.lpf);
- }
- } Tree[maxn * 4];
-
- int arr[maxn];
-
- void build(int node, int a, int b)
- {
- if (a == b) return void(Tree[node].assignLeaf(arr[a], sp[ arr[a] ]));
- int lchild = node * 2;
- int rchild = lchild + 1;
- int mid = (a + b) / 2;
- build(lchild, a, mid);
- build(rchild, mid + 1, b);
- Tree[node].marge(Tree[lchild], Tree[rchild]);
- }
-
- void update(int node, int a, int b, int i, int j)
- {
- if (a > j or b < i) return;
- if (a == b)
- {
- int num = Tree[node].num / sp[ Tree[node].num ];
- int lpf = max(1, sp[num]);
- Tree[node].assignLeaf(num, lpf);
- return;
- }
- int lchild = node * 2;
- int rchild = lchild + 1;
- int mid = (a + b) / 2;
- if (Tree[lchild].num >= 2) update(lchild, a, mid, i, j);
- if (Tree[rchild].num >= 2) update(rchild, mid + 1, b, i, j);
- Tree[node].marge(Tree[lchild], Tree[rchild]);
- }
-
- int query(int node, int a, int b, int i, int j)
- {
- if (a > j or b < i) return 1;
- if (a >= i and b <= j) return Tree[node].lpf;
- int lchild = node * 2;
- int rchild = lchild + 1;
- int mid = (a + b) / 2;
- int p = query(lchild, a, mid, i, j);
- int q = query(rchild, mid + 1, b, i, j);
- return max(p, q);
- }
-
- signed main()
- {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.tie(nullptr);
-
- sieve();
-
- int tc;
- cin >> tc;
- while (tc--)
- {
- int n, m;
- cin >> n >> m;
- for (int i = 1; i <= n; i++) cin >> arr[i];
- build(1, 1, n);
- while (m--)
- {
- int type, l, r;
- cin >> type >> l >> r;
- if (type == 0) update(1, 1, n, l, r);
- else cout << query(1, 1, n, l, r) << ' ';
- for (int i = 1; i <= n; i++) cerr << query(1, 1, n, i, i) << ", ";
- cerr << endl;
- }
- cout << endl;
- }
- }