Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Слава Україні, Героям слава
- #include <bits/stdc++.h>
- using namespace std;
- const int mod = 1e9 + 7, N = 1e7 + 1;
- struct LCA {
- //one indexed shit
- int n, l;
- vector<vector<int>> adj, up;
- vector<int> h;
- LCA (int n_) {
- n = n_;
- l = 31 - __builtin_clz(n);
- adj.resize(n + 1);
- up.assign(n + 1, vector<int>(l + 1));
- h.resize(n + 1);
- }
- void add(int a, int b) {
- adj[a].push_back(b);
- adj[b].push_back(a);
- }
- void dfs(int v = 1, int p = 0, int hh = 0) {
- up[v][0] = p;
- for(int i = 1; i <= l; i++) {
- up[v][i] = up[up[v][i - 1]][i - 1];
- }
- for(auto u : adj[v]) {
- if(u != p) {
- dfs(u, v, hh + 1);
- }
- }
- h[v] = hh;
- }
- int lca(int a, int b) {
- if(h[a] > h[b]) {
- swap(a, b);
- }
- int dff = h[b] - h[a], cnt = 0;
- while(dff) {
- if(dff & 1) {
- b = up[b][cnt];
- }
- cnt++;
- dff >>= 1;
- }
- if(a == b) {
- return a;
- }
- for(int i = l; i >= 0; i--) {
- if(up[a][i] != up[b][i]) {
- a = up[a][i];
- b = up[b][i];
- }
- }
- return up[a][0];
- }
- int raise(int node, int dist) {
- //if it returns 0, then it fucked up
- int cnt = 0;
- while(dist) {
- if(dist & 1) {
- node = up[node][cnt];
- }
- cnt++;
- dist >>= 1;
- }
- return node;
- }
- int dist(int a, int b) {
- int z = lca(a, b);
- return h[a] + h[b] - 2 * h[z];
- }
- };
- long long binexp(long long a, long long n) {
- long long res = 1;
- while(n) {
- if(n & 1) {
- res = (res * a) % mod;
- }
- a = (a * a) % mod;
- n >>= 1;
- }
- return res;
- }
- int lp[N];
- bool comp[N];
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- for(long long i = 2; i < N; i++) {
- if(!comp[i]) {
- lp[i] = i;
- for(long long j = i * i; j < N; j += i) {
- lp[j] = i;
- comp[j] = true;
- }
- }
- }
- int n, q;
- cin >> n >> q;
- map<int, int> mp[n + 1];
- for(int i = 1; i <= n; i++) {
- int x;
- cin >> x;
- while(x > 1) {
- mp[i][lp[x]]++;
- x /= lp[x];
- }
- }
- LCA lca(n);
- for(int i = 1; i < n; i++) {
- int a, b;
- cin >> a >> b;
- lca.add(a, b);
- }
- lca.dfs();
- while(q--) {
- int t, a, b;
- cin >> t >> a >> b;
- if(t == 1) {
- int c = lca.lca(a, b);
- map<int, int> ans;
- while(a != c) {
- for(auto e : mp[a]) {
- ans[e.first] = max(ans[e.first], e.second);
- }
- a = lca.raise(a, 1);
- }
- a = b;
- while(a != c) {
- for(auto e : mp[a]) {
- ans[e.first] = max(ans[e.first], e.second);
- }
- a = lca.raise(a, 1);
- }
- for(auto e : mp[c]) {
- ans[e.first] = max(ans[e.first], e.second);
- }
- long long res = 1;
- for(auto e : ans) {
- res = (res * binexp(e.first, e.second)) % mod;
- }
- cout << res << "\n";
- } else {
- while(b > 1) {
- mp[a][lp[b]]++;
- b /= lp[b];
- }
- }
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment