Sunday, August 16, 2020

[Codeforces] D. Yaroslav and Divisors

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : D. Yaroslav and Divisors
Source            : Codeforces
Category          : Data Structure
Algorithm         : 
Verdict           : Accepted

Tutorial : https://duoblogger.github.io/offline-query-solution-1/

  1. #undef _GLIBCXX_DEBUG  
  2.   
  3. #include "bits/stdc++.h"  
  4. #include "ext/pb_ds/assoc_container.hpp"  
  5. #include "ext/pb_ds/tree_policy.hpp"  
  6. #include "ext/rope"  
  7.   
  8. using namespace std;  
  9. using namespace __gnu_pbds;  
  10. using namespace __gnu_cxx;  
  11.   
  12. void trace(int x)                         { cerr << x; }  
  13. void trace(long x)                        { cerr << x; }  
  14. void trace(long long x)                   { cerr << x; }  
  15. void trace(unsigned x)                    { cerr << x; }  
  16. void trace(unsigned long x)               { cerr << x; }  
  17. void trace(unsigned long long x)          { cerr << x; }  
  18. void trace(float x)                       { cerr << x; }  
  19. void trace(double x)                      { cerr << x; }  
  20. void trace(long double x)                 { cerr << x; }  
  21. void trace(char x)                        { cerr << '\'' << x << '\''; }  
  22. void trace(const char *x)                 { cerr << '\"' << x << '\"'; }  
  23. void trace(const string &x)               { cerr << '\"' << x << '\"'; }  
  24. void trace(bool x)                        { cerr << (x ? "true" : "false"); }  
  25.   
  26. template <typename A, typename B>                         void trace(const pair <A, B> &x)         { cerr << '{'; trace(x.first); cerr << ','; trace(x.second); cerr << '}'; }  
  27. template <typename A, typename B, typename C>             void trace(const tuple <A, B, C> &x)     { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << '}'; }  
  28. template <typename A, typename B, typename C, typename D> void trace(const tuple <A, B, C, D> &x)  { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << ','; trace(get <3> (x)); cerr << '}'; }  
  29. template <typename T>                                     void trace(const T &x)                   { int f = 0; cerr << '{'for (auto &i: x) cerr << (f++ ? "," : ""), trace(i); cerr << "}"; }  
  30. template <size_t N>                                       void trace(bitset <N> v)                 { cerr << '{'for (size_t i = 0; i < N; i++) cerr << static_cast <char> ('0' + v[i]); cerr << '}'; }  
  31. void _print()                                                                                      { cerr << "]\n"; }  
  32. template <typename T, typename... V>                      void _print(T t, V... v)                 { trace(t); if (sizeof...(v)) cerr << ", "; _print(v...); }  
  33.   
  34. #ifndef ONLINE_JUDGE  
  35.       #define debug(x...) cerr << "[" << #x << "] = ["; _print(x)  
  36. #else  
  37.       #define debug(x...)  
  38. #endif // ONLINE_JUDGE  
  39.   
  40. template <typename T> using ordered_set                = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;  
  41. template <typename T1, typename T2> using ordered_map  = tree <T1, T2, less <T1>, rb_tree_tag, tree_order_statistics_node_update>;  
  42.   
  43. template <class T> T binaryExpo(T a, T p)              { if (p == 0) { return 1LL; } if (p == 1) { return a; } if (p & 1) { return a * binaryExpo(a, p - 1); } T ret = binaryExpo(a, p / 2); return ret * ret; }  
  44. template <class T> T bigMod(T a, T p, T m)             { if (p == 0) { return 1LL % m; } if (p == 1) { return a % m; } if (p & 1) { return (a % m * bigMod(a, p - 1, m)) % m; } T ret = bigMod(a, p / 2, m) % m; return (ret * ret) % m; }  
  45. template <class T> T modInv(T a, T m)                  { return bigMod(a, m - 2, m); }  
  46.   
  47. template <class T> bool MIN(T &a, T b)                 { return a > b ? (a = b, true) : false; }  
  48. template <class T> bool MAX(T &a, T b)                 { return a < b ? (a = b, true) : false; }  
  49.   
  50. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());  
  51.   
  52. #define ll              long long int  
  53. #define ull             unsigned long long int  
  54. #define ld              long double  
  55. #define endl            '\n'  
  56. #define pii             pair <int, int>  
  57. #define pll             pair <ll, ll>  
  58. #define mk              make_pair  
  59. #define ff              first  
  60. #define ss              second  
  61. #define all(a)          (a).begin(), (a).end()  
  62. #define rall(a)         (a).rbegin(), (a).rend()  
  63. #define eb              emplace_back  
  64. #define pb              push_back  
  65. #define pf              push_front  
  66. #define sz(a)           (int)(a.size())  
  67. #define ook             order_of_key             // The number of items in a set that are strictly smaller than k  
  68. #define fbo             find_by_order            // It returns an iterator to the i'th largest element  
  69. #define ATCODER         if (fopen("in.txt", "r")) { freopen("in.txt", "r", stdin); }  
  70.   
  71. #define int             long long int  
  72.   
  73. const int maxn = 2e5 + 5;  
  74. const int logn = 19;  
  75. const long long MOD = 1000000007;  
  76. const long long INF = 1e18;  
  77.   
  78. vector < vector <int> > divisor;  
  79.   
  80. void seive() {  
  81.       divisor.resize(maxn);  
  82.       for (int i = 1; i < maxn; i++) {  
  83.             for (int j = 1; 1LL * i * j < maxn; j++) {  
  84.                   divisor[i * j].push_back(i);  
  85.             }  
  86.       }  
  87. }  
  88.   
  89. int Tree[maxn];  
  90.   
  91. void update(int pos, int val = 1) {  
  92.       while (pos < maxn) {  
  93.             Tree[pos] += val;  
  94.             pos += (pos & -pos);  
  95.       }  
  96. }  
  97.   
  98. int query(int pos) {  
  99.       int sum = 0;  
  100.       while (pos > 0) {  
  101.             sum += Tree[pos];  
  102.             pos -= (pos & -pos);  
  103.       }  
  104.       return sum;  
  105. }  
  106.   
  107. int query(int l, int r) {  
  108.       return query(r) - query(l - 1);  
  109. }  
  110.   
  111. struct Query {  
  112.       int l, r, id;  
  113.       Query(int l = 0, int r = 0, int id = 0)  
  114.             : l(l), r(r), id(id) {}  
  115. };  
  116.   
  117. signed main()  
  118. {  
  119.       ios_base::sync_with_stdio(false);  
  120.       cin.tie(nullptr); cout.tie(nullptr);  
  121.       cout.precision(12);  
  122.   
  123.       bool FILEIO = 0;  
  124.       if (FILEIO and fopen("in.txt""r")) {  
  125.             freopen("in.txt""r", stdin);  
  126.       }  
  127.   
  128.       seive();  
  129.   
  130.       int n, q;  
  131.       cin >> n >> q;  
  132.       vector <int> arr(n + 1);  
  133.       vector <int> position(n + 1);  
  134.       for (int i = 1; i <= n; i++) {  
  135.             cin >> arr[i];  
  136.             position[ arr[i] ] = i;  
  137.       }  
  138.       vector <Query> queries;  
  139.       for (int i = 1; i <= q; i++) {  
  140.             int l, r;  
  141.             cin >> l >> r;  
  142.             queries.emplace_back(l, r, i);  
  143.       }  
  144.       vector <int> ans(q + 1);  
  145.       sort(queries.begin(), queries.end(), [&](Query p, Query q)  
  146.            {  
  147.                  return p.r < q.r;  
  148.            });  
  149.       int l = 0;  
  150.       for (Query it : queries) {  
  151.             while (l < it.r) {  
  152.                   ++l;  
  153.                   for (int d : divisor[ arr[l] ]) {  
  154.                         int pos = position[d];  
  155.                         if (pos <= l) update(pos);  
  156.                   }  
  157.             }  
  158.             ans[it.id] = query(it.l, it.r);  
  159.       }  
  160.       memset(Tree, 0, sizeof Tree);  
  161.       sort(queries.begin(), queries.end(), [&](Query p, Query q)  
  162.            {  
  163.                  return p.l > q.l;  
  164.            });  
  165.       int r = n + 1;  
  166.       for (Query it : queries) {  
  167.             while (r > it.l) {  
  168.                   --r;  
  169.                   for (int d : divisor[ arr[r] ]) {  
  170.                         int pos = position[d];  
  171.                         if (pos > r) {  
  172.                               update(pos);  
  173.                         }  
  174.                   }  
  175.             }  
  176.             ans[it.id] += query(it.l, it.r);  
  177.       }  
  178.       for (int i = 1; i <= q; i++) {  
  179.             cout << ans[i] << endl;  
  180.       }  
  181.   
  182.   
  183.       #ifndef ONLINE_JUDGE  
  184.             cerr << endl << "Time : " << 1.0 * clock() / CLOCKS_PER_SEC << " s." << endl;  
  185.       #endif // ONLINE_JUDGE  
  186. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.