Showing posts with label Codechef. Show all posts
Showing posts with label Codechef. Show all posts

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. }  

Tuesday, November 12, 2019

[Codechef] POLY - Polynomials

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : POLY - Polynomials 
Source            : Codeforces
Category          : Data Structure
Algorithm         : Li Chao Tree
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. static const int maxn = 2e5 + 5;  
  6. static const int offset = 350; // Bruteforce for this limit  
  7. static const long long inf = 1e18;  
  8.   
  9. struct Line  
  10. {  
  11.       long long a;  
  12.       long long b;  
  13.       long long c;  
  14.       long long d;  
  15.   
  16.       Line(long long a = inf, long long b = 0, long long c = 0, long long d = 0)  
  17.             : a(a)  
  18.             , b(b)  
  19.             , c(c)  
  20.             , d(d) {}  
  21.   
  22.       long long evalute(long long x)  
  23.       {  
  24.             return a + b * x + c * x * x + d * x * x * x;  
  25.       }  
  26. } Tree[maxn * 4];  
  27.   
  28. int N = 1e5; // Maximum Query Points  
  29. long long aux[offset + 5];  
  30.   
  31. void init()  
  32. {  
  33.       for (int i = 0; i < offset; i++) aux[i] = inf;  
  34.       for (int i = 0; i < maxn * 4; i++) Tree[i] = Line();  
  35. }  
  36.   
  37. int compare(long long x, long long y)  
  38. {  
  39.       if (x < y) return -1;  
  40.       return x > y;  
  41. }  
  42.   
  43. void update(int node, int a, int b, int i, int j, Line fx)  
  44. {  
  45.       if (a > j or b < i) return;  
  46.       int lchild = node * 2;  
  47.       int rchild = lchild + 1;  
  48.       int mid = (a + b) / 2;  
  49.       if (a >= i and b <= j)  
  50.       {  
  51.             // fx         = new function  
  52.             // Tree[node] = old function  
  53.   
  54.             int fa = compare(fx.evalute(a), Tree[node].evalute(a));  
  55.             int fb = compare(fx.evalute(b), Tree[node].evalute(b));  
  56.             int fm1 = compare(fx.evalute(mid), Tree[node].evalute(mid));  
  57.             int fm2 = compare(fx.evalute(mid + 1), Tree[node].evalute(mid + 1));  
  58.   
  59.             // New function is worse for a to b, no point of adding it  
  60.             if (fa >= 0 and fb >= 0) return;  
  61.   
  62.             // New function is better for a to b, add it  
  63.             if (fa <= 0 and fb <= 0)  
  64.             {  
  65.                   Tree[node] = fx;  
  66.                   return;  
  67.             }  
  68.   
  69.             // New function is better for a to mid, add it. Old function can still be  
  70.             // better for right segment.  
  71.             if (fa <= 0 and fm1 <= 0)  
  72.             {  
  73.                   // Sending the old function to the right segment  
  74.                   update(rchild, mid + 1, b, i, j, Tree[node]);  
  75.                   Tree[node] = fx;  
  76.                   return;  
  77.             }  
  78.   
  79.             // New function is worse for a to mid, but this can be better for right segment.  
  80.             if (fa >= 0 and fm1 >= 0)  
  81.             {  
  82.                   update(rchild, mid + 1, b, i, j, fx);  
  83.                   return;  
  84.             }  
  85.   
  86.             // New function worse for mid + 1 to b, but can be better for left segment  
  87.             if (fm2 >= 0 and fb >= 0)  
  88.             {  
  89.                   update(lchild, a, mid, i, j, fx);  
  90.                   return;  
  91.             }  
  92.   
  93.             // New function better for mid + 1 to b, add it. Old function can still be better  
  94.             // for left.  
  95.             if (fm2 <= 0 and fb <= 0)  
  96.             {  
  97.                   update(lchild, a, mid, i, j, Tree[node]);  
  98.                   Tree[node] = fx;  
  99.                   return;  
  100.             }  
  101.       }  
  102.       else if (a < b)  
  103.       {  
  104.             update(lchild, a, mid, i, j, fx);  
  105.             update(rchild, mid + 1, b, i, j, fx);  
  106.       }  
  107. }  
  108.   
  109. long long query(int node, int a, int b, long long x)  
  110. {  
  111.       if (a == b) return Tree[node].evalute(x);  
  112.       int lchild = node * 2;  
  113.       int rchild = lchild + 1;  
  114.       int mid = (a + b) / 2;  
  115.       long long ret = Tree[node].evalute(x);  
  116.       if (x <= mid) ret = min(ret, query(lchild, a, mid, x));  
  117.       else ret = min(ret, query(rchild, mid + 1, b, x));  
  118.       return ret;  
  119. }  
  120.   
  121. void calc(Line fx)  
  122. {  
  123.       for (int x = 0; x < offset; x++)  
  124.       {  
  125.             aux[x] = min(aux[x], fx.evalute(x));  
  126.       }  
  127. }  
  128.   
  129. signed main()  
  130. {  
  131.       ios_base::sync_with_stdio(false);  
  132.       cin.tie(nullptr);  
  133.       cout.tie(nullptr);  
  134.   
  135.       #ifndef ONLINE_JUDGE  
  136.             freopen("in.txt""r", stdin);  
  137.       #endif // ONLINE_JUDGE  
  138.   
  139.       int tc;  
  140.       cin >> tc;  
  141.       for (int tcase = 1; tcase <= tc; tcase++)  
  142.       {  
  143.             int n;  
  144.             cin >> n;  
  145.             init();  
  146.             for (int i = 0; i < n; i++)  
  147.             {  
  148.                   Line fx;  
  149.                   cin >> fx.a >> fx.b >> fx.c >>  fx.d;  
  150.                   calc(fx);  
  151.                   update(1, 1, N, offset, N, fx);  
  152.             }  
  153.             int q;  
  154.             cin >> q;  
  155.             while (q--)  
  156.             {  
  157.                   long long x;  
  158.                   cin >> x;  
  159.                   long long minval;  
  160.                   if (x < offset) minval = aux[x];  
  161.                   else minval = query(1, 1, N, x);  
  162.                   cout << minval << '\n';  
  163.             }  
  164.       }  
  165. }