Friday, February 7, 2020

[Codechef] DIVMAC - Dividing Machine

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

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll           long long int   
  6. #define endl         '\n'  
  7.   
  8. static const int maxn = 2e6 + 5;  
  9.   
  10. bool isprime[maxn];  
  11. vector <int> prime;  
  12. int sp[maxn];  
  13.   
  14. void sieve()  
  15. {  
  16.     for (int i = 2; i < maxn; i++) isprime[i] = true;  
  17.     sp[2] = 2;  
  18.     for (int i = 4; i < maxn; i += 2) isprime[i] = false, sp[i] = 2;  
  19.     for (long long i = 3; i < maxn; i += 2)  
  20.     {  
  21.         if (isprime[i])  
  22.         {  
  23.             sp[i] = i;  
  24.             for (long long j = i; i * j < maxn; j += 2)  
  25.             {  
  26.                 if (isprime[i * j])  
  27.                 {  
  28.                     isprime[i * j] = false;  
  29.                     sp[i * j] = i;  
  30.                 }  
  31.             }  
  32.         }  
  33.     }  
  34.     prime.push_back(2);  
  35.     for (int i = 3; i < maxn; i += 2) if (isprime[i]) prime.push_back(i);  
  36. }  
  37.   
  38. struct SegmentTree  
  39. {  
  40.     int num;  
  41.     int lpf;  
  42.     SegmentTree(int num = 0, int lpf = 0) : num(num), lpf(lpf) {}  
  43.       
  44.     void assignLeaf(int x, int y)  
  45.     {  
  46.         num = x;  
  47.         lpf = y;  
  48.     }  
  49.     void marge(const SegmentTree &lchild, const SegmentTree &rchild)  
  50.     {  
  51.         num = max(lchild.num, rchild.num);  
  52.         lpf = max(lchild.lpf, rchild.lpf);  
  53.     }  
  54. } Tree[maxn * 4];  
  55.   
  56. int arr[maxn];  
  57.   
  58. void build(int node, int a, int b)  
  59. {  
  60.     if (a == b) return void(Tree[node].assignLeaf(arr[a], sp[ arr[a] ]));  
  61.     int lchild = node * 2;  
  62.     int rchild = lchild + 1;  
  63.     int mid = (a + b) / 2;  
  64.     build(lchild, a, mid);  
  65.     build(rchild, mid + 1, b);  
  66.     Tree[node].marge(Tree[lchild], Tree[rchild]);  
  67. }  
  68.   
  69. void update(int node, int a, int b, int i, int j)  
  70. {  
  71.     if (a > j or b < i) return;  
  72.     if (a == b)   
  73.     {  
  74.         int num = Tree[node].num / sp[ Tree[node].num ];  
  75.         int lpf = max(1, sp[num]);  
  76.         Tree[node].assignLeaf(num, lpf);  
  77.         return;  
  78.     }  
  79.     int lchild = node * 2;  
  80.     int rchild = lchild + 1;  
  81.     int mid = (a + b) / 2;  
  82.     if (Tree[lchild].num >= 2) update(lchild, a, mid, i, j);  
  83.     if (Tree[rchild].num >= 2) update(rchild, mid + 1, b, i, j);  
  84.     Tree[node].marge(Tree[lchild], Tree[rchild]);  
  85. }  
  86.   
  87. int query(int node, int a, int b, int i, int j)  
  88. {  
  89.     if (a > j or b < i) return 1;  
  90.     if (a >= i and b <= j) return Tree[node].lpf;  
  91.     int lchild = node * 2;  
  92.     int rchild = lchild + 1;  
  93.     int mid = (a + b) / 2;  
  94.     int p = query(lchild, a, mid, i, j);  
  95.     int q = query(rchild, mid + 1, b, i, j);  
  96.     return max(p, q);   
  97. }  
  98.   
  99. signed main()  
  100. {  
  101.     ios_base::sync_with_stdio(false);  
  102.     cin.tie(nullptr);  
  103.     cout.tie(nullptr);  
  104.       
  105.     sieve();  
  106.       
  107.     int tc;  
  108.     cin >> tc;  
  109.     while (tc--)  
  110.     {  
  111.         int n, m;  
  112.         cin >> n >> m;  
  113.         for (int i = 1; i <= n; i++) cin >> arr[i];  
  114.         build(1, 1, n);  
  115.         while (m--)  
  116.         {  
  117.             int type, l, r;  
  118.             cin >> type >> l >> r;  
  119.             if (type == 0) update(1, 1, n, l, r);  
  120.             else cout << query(1, 1, n, l, r) << ' ';  
  121.             for (int i = 1; i <= n; i++) cerr << query(1, 1, n, i, i) << ", ";  
  122.             cerr << endl;  
  123.         }  
  124.         cout << endl;  
  125.     }  
  126. }  

Thursday, January 30, 2020

[Toph] Jontrona of Liakot

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : Jontrona of Liakot
Source            : Toph.co
Category          : Data Structure, Graph Theory, Tree
Algorithm         : Persistent Trie
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll           long long int  
  6. #define endl         '\n'  
  7.   
  8. static const int maxn = 2e5 + 5;  
  9. static const int maxp = 6e6 + 6;  
  10.   
  11. struct Node  
  12. {  
  13.       int st;  
  14.       int lchild;  
  15.       int rchild;  
  16.       Node(int st = 0, int lchild = 0, int rchild = 0)  
  17.             : st(st)  
  18.             , lchild(lchild)  
  19.             , rchild(rchild) {}  
  20. } Tree[maxp];  
  21.   
  22. int version[maxn];  
  23. int NODES;  
  24.   
  25. int update(int root, int pos, int val)  
  26. {  
  27.       int newNode = ++NODES;  
  28.       Tree[newNode] = Tree[root];  
  29.       if (pos < 0)  
  30.       {  
  31.             Tree[newNode].st += 1;  
  32.             return newNode;  
  33.       }  
  34.       int bit = (bool)(val & (1 << pos));  
  35.       if (bit == 0) Tree[newNode].lchild = update(Tree[newNode].lchild, pos - 1, val);  
  36.       else Tree[newNode].rchild = update(Tree[newNode].rchild, pos - 1, val);  
  37.       Tree[newNode].st = Tree[ Tree[newNode].lchild ].st + Tree[ Tree[newNode].rchild ].st;  
  38.       return newNode;  
  39. }  
  40.   
  41. int kth(int root1, int root2, int root3, int root4, int pos, int k, int xor_val)  
  42. {  
  43.       if (pos < 0) return 0;  
  44.       bool bit = (bool)(xor_val & (1 << pos));  
  45.       int bad = 0;  
  46.       if (bit == 0)  
  47.       {  
  48.             bad = Tree[ Tree[root4].lchild ].st - Tree[ Tree[root1].lchild ].st -  
  49.                   Tree[ Tree[root3].lchild ].st + Tree[ Tree[root2].lchild ].st;  
  50.             if (bad < k) return (1 << pos) + kth(Tree[root1].rchild, Tree[root2].rchild, Tree[root3].rchild, Tree[root4].rchild, pos - 1, k - bad, xor_val);  
  51.             else return kth(Tree[root1].lchild, Tree[root2].lchild, Tree[root3].lchild, Tree[root4].lchild, pos - 1, k, xor_val);  
  52.       }  
  53.       else  
  54.       {  
  55.             bad = Tree[ Tree[root4].rchild ].st - Tree[ Tree[root1].rchild ].st -  
  56.                   Tree[ Tree[root3].rchild ].st + Tree[ Tree[root2].rchild ].st;  
  57.             if (bad < k) return (1 << pos) + kth(Tree[root1].lchild, Tree[root2].lchild, Tree[root3].lchild, Tree[root4].lchild, pos - 1, k - bad, xor_val);  
  58.             else kth(Tree[root1].rchild, Tree[root2].rchild, Tree[root3].rchild, Tree[root4].rchild, pos - 1, k, xor_val);  
  59.       }  
  60. }  
  61.   
  62. vector < vector <int> > graph;  
  63. int in[maxn];  
  64. int out[maxn];  
  65. int which[maxn];  
  66. int dfsTime;  
  67.   
  68. void dfs(int u = 1, int p = -1)  
  69. {  
  70.       in[u] = ++dfsTime;  
  71.       which[dfsTime] = u;  
  72.       for (int v : graph[u])  
  73.       {  
  74.             if (v == p) continue;  
  75.             dfs(v, u);  
  76.       }  
  77.       out[u] = dfsTime;  
  78. }  
  79.   
  80. int arr[maxn];  
  81.   
  82. signed main()  
  83. {  
  84.       ios_base::sync_with_stdio(false);  
  85.       cin.tie(nullptr);  
  86.       cout.tie(nullptr);  
  87.   
  88.       #ifndef ONLINE_JUDGE  
  89.             freopen("in.txt""r", stdin);  
  90.       #endif // ONLINE_JUDGE  
  91.   
  92.       int n, q;  
  93.       cin >> n >> q;  
  94.       for (int i = 1; i <= n; i++) cin >> arr[i];  
  95.       graph.resize(n + 1);  
  96.       for (int e = 1; e < n; e++)  
  97.       {  
  98.             int u, v;  
  99.             cin >> u >> v;  
  100.             graph[u].push_back(v);  
  101.             graph[v].push_back(u);  
  102.       }  
  103.       dfs();  
  104.       for (int i = 1; i <= n; i++) version[i] = update(version[i - 1], 30, arr[ which[i] ]);  
  105.       while (q--)  
  106.       {  
  107.             int u, v, z, k;  
  108.             cin >> u >> v >> z >> k;  
  109.             int root1 = version[ in[u] - 1 ];  
  110.             int root2 = version[ in[v] - 1 ];  
  111.             int root3 = version[ out[v] ];  
  112.             int root4 = version[ out[u] ];  
  113.             int sze = out[u] - in[u] + 1 - (out[v] - in[v] + 1);  
  114.             if (sze < k)  
  115.             {  
  116.                   cout << "-1" << endl;  
  117.             }  
  118.             else  
  119.             {  
  120.                   int ans = kth(root1, root2, root3, root4, 30, k, z);  
  121.                   cout << ans << endl;  
  122.             }  
  123.       }  
  124. }