Saturday, June 22, 2019

[Codechef] TAQTREE - Queries On Tree

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : TAQTREE - Queries On Tree
Source            : Codechef
Category          : Graph Theory, Tree
Algorithm         : Easiest HLD Over Subtree and Paths 
Verdict           : Accepted

#include "bits/stdc++.h"
 
using namespace std;
 
static const int maxn = 2e5 + 5;
static const int logn = 19;
 
struct Edge
{
      int v, w, id;
      Edge(int v = 0, int w = 0, int id = 0) : v(v), w(w), id(id) {}
};
 
vector <Edge> graph[maxn];
vector <int> Tree[maxn];
int subtreeSize[maxn], Id[maxn];
int depth[maxn], father[maxn][logn];
int nxt[maxn], in[maxn], out[maxn], tym, nodeCost[maxn];
 
void makeTree(int u = 1, int p = -1)
{
      for (Edge e : graph[u])
      {
            int v = e.v;
            int w = e.w;
            int id = e.id;
            if (v == p) continue;
            Tree[u].push_back(v);
            nodeCost[v] = w;
            Id[id] = v;
            makeTree(v, u);
      }
}
 
void dfsSize(int u = 1)
{
      for (int i = 1; i < logn; i++) father[u][i] = father[ father[u][i-1] ][i-1];
      for (int v : Tree[u])
      {
            dfsSize(v);
            subtreeSize[u] += subtreeSize[v];
            if (subtreeSize[v] > subtreeSize[ Tree[u][0] ]) swap(v, Tree[u][0]);
      }
}
 
void hld(int u = 1)
{
      in[u] = ++tym;
      for (int v : Tree[u])
      {
            nxt[v] = v == Tree[u][0] ? nxt[u] : v;
            hld(v);
      }
      out[u] = tym;
}
 
void dfs(int u = 1)
{
      for (int i = 1; i < logn; i++) father[u][i] = father[ father[u][i-1] ][i-1];
      for (int v : Tree[u])
      {
            depth[v] = depth[u] + 1;
            father[v][0] = u;
            dfs(v);
      }
}
 
int findLCA(int u, int v)
{
      if (depth[u] < depth[v]) swap(u, v);
      for (int i = logn - 1; i >= 0; i--)
      {
            if (depth[ father[u][i] ] >= depth[v]) u = father[u][i];
      }
      if (u == v) return u;
      for (int i = logn - 1; i >= 0; i--)
      {
            if (father[u][i] != father[v][i])
            {
                  u = father[u][i];
                  v = father[v][i];
            }
      }
      return father[u][0];
}
 
int segTree[maxn * 4];
int arr[maxn], N;
 
void update(int node, int a, int b, int pos, int val)
{
      if (a > pos or b < pos) return;
      if (a >= pos and b <= pos)
      {
            segTree[node] = val;
            return;
      }
      int lft = node << 1;
      int rgt = lft | 1;
      int mid = a + b >> 1;
      update(lft, a, mid, pos, val);
      update(rgt, mid + 1, b, pos, val);
      segTree[node] = segTree[lft] + segTree[rgt];
}
 
int query(int node, int a, int b, int i, int j)
{
      if (a > j or b < i) return 0;
      if (a >= i and b <= j) return segTree[node];
      int lft = node << 1;
      int rgt = lft | 1;
      int mid = a + b >> 1;
      int p = query(lft, a, mid, i, j);
      int q = query(rgt, mid + 1, b, i, j);
      return p + q;
}
 
int queryUp(int u, int v)
{
      // u = niche, v = lca
      int sum = 0;
      int L = in[v];
      while (true)
      {
            int l = in[ nxt[u] ];
            int r = in[u];
            if (l <= L)
            {
                  l = max(l, L);
                  sum += query(1, 1, N, l, r);
                  break;
            }
            sum += query(1, 1, N, l, r);
            u = father[ nxt[u] ][0];
      }
      return sum;
}
 
int queryhld(int u, int v)
{
      int lca = findLCA(u, v);
      int lft = queryUp(u, lca);
      int rgt = queryUp(v, lca);
      int middle = queryUp(lca, lca);
      return queryUp(u, lca) + queryUp(v, lca) - 2 * queryUp(lca, lca);
}
 
void updatehld(int u, int val)
{
      nodeCost[u] = val;
      update(1, 1, N, in[u], val);
}
 
int main()
{
      ios_base::sync_with_stdio(false);
      cin.tie(nullptr);
      cout.tie(nullptr);
 
      #ifndef ONLINE_JUDGE
            freopen("in.txt", "r", stdin);
      #endif // ONLINE_JUDGE
 
 
      int tnode;
      cin >> tnode;
      for (int e = 1; e < tnode; e++)
      {
            int u, v, w;
            cin >> u >> v >> w;
            graph[u].emplace_back(v, w, e);
            graph[v].emplace_back(u, w, e);
      }
      makeTree();
      dfsSize();
      nxt[1] = 1;
      hld();
      depth[1] = 1;
      dfs();
      N = tnode;
 
      for (int i = 1; i <= tnode; i++)
      {
//            cerr << i << ' ' << nodeCost[i] << ' ' << Id[i] << endl;
            updatehld(i, nodeCost[i]);
      }
 
      int q;
      cin >> q;
      while (q--)
      {
            int type;
            cin >> type;
            if (type == 1)
            {
                  int id, val;
                  cin >> id >> val;
                  updatehld(Id[id], val);
            }
            else
            {
                  int u, v;
                  cin >> u >> v;
                  cout << queryhld(u, v) << endl;
            }
      }
}
 

Tuesday, June 18, 2019

[Codechef] SEGPROD - Product on the segment by modulo

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : SEGPROD - Product on the segment by modulo
Source            : Codechef
Category          : Data Structure
Algorithm         : Disjoint Sparse Table 
Verdict           : Accepted

  1. #include <bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll                long long  
  6.   
  7. static const int maxn = 3e6 + 50;  
  8. static const int Max = 2e7 + 5;  
  9. static const int logn = 20;  
  10.   
  11. ll arr[maxn], dst[maxn][logn];  
  12. ll p;  
  13. ll queries[Max];  
  14.   
  15. ll mul(ll a, ll b)  
  16. {  
  17.       return (a * b) % p;  
  18. }  
  19.   
  20. void buildDST(int h, int l, int r)  
  21. {  
  22.       if (h < 0) return;  
  23.       int mid = (l + r) >> 1;  
  24.       ll product = 1;  
  25.       for (int i = mid - 1; i >= l; i--)  // Suffix calculation  
  26.       {  
  27.             dst[i][h] = mul(product, arr[i]);  
  28.             product = mul(product, arr[i]);  
  29.       }  
  30.       product = 1;  
  31.       for (int i = mid; i < r; i++) // Prefix calculation  
  32.       {  
  33.             dst[i][h] = mul(product, arr[i]);  
  34.             product = mul(product, arr[i]);  
  35.       }  
  36.       buildDST(h-1, l, mid);  
  37.       buildDST(h-1, mid, r);  
  38. }  
  39.   
  40. ll query(int l, int r)  
  41. {  
  42.       if (l == r) return arr[l]; // Base Case  
  43.       int h = 31 - __builtin_clz(l ^ r);  
  44.       return mul(dst[l][h], dst[r][h]);  
  45. }  
  46.   
  47. void solve()  
  48. {  
  49.       int n, q;  
  50.       cin >> n >> p >> q;  
  51.       for (int i = 0; i < n; i++)  
  52.       {  
  53.             cin >> arr[i];  
  54.             arr[i] %= p;  
  55.       }  
  56.       int h = 1;  
  57.       while ((1 << h) < n) ++h;  
  58.       buildDST(h-1, 0, (1 << h));  
  59.       int totalQuery = q / 64 + 2;  
  60.       for (int i = 0; i < totalQuery; i++) cin >> queries[i];  
  61.       ll l = 0, r = 0;  
  62.       ll last = 0;  
  63.       for (int i = 0; i < q; i++)  
  64.       {  
  65.             if (i % 64 == 0)  
  66.             {  
  67.                   l = (queries[i / 64] + last) % n;  
  68.                   r = (queries[i / 64 + 1] + last) % n;  
  69.             }  
  70.             else  
  71.             {  
  72.                   l = (l + last) % n;  
  73.                   r = (r + last) % n;  
  74.             }  
  75.             if (l > r) swap(l, r);  
  76.             ll ans = query(l, r);  
  77.             last = (ans + 1) % p;  
  78.       }  
  79.       cout << last << '\n';  
  80. }  
  81.   
  82. int 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 tc;  
  93.       cin >> tc;  
  94.       for (int tcase = 1; tcase <= tc; tcase++) solve();  
  95. }