Wednesday, July 31, 2019

[Template] Convex Hull


  1. struct Point {  
  2.       int x, y;  
  3.       Point(int x = 0, int y = 0)  
  4.             : x(x), y(y) {}  
  5. };  
  6.   
  7. bool cmp(Point a, Point b) {  
  8.       return a.x < b.x || (a.x == b.x && a.y < b.y);  
  9. }  
  10.   
  11. bool cw(Point a, Point b, Point c) {  
  12.       return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) < 0;  
  13. }  
  14.   
  15. bool ccw(Point a, Point b, Point c) {  
  16.     return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) > 0;  
  17. }  
  18.   
  19. vector <Point> convex_hull(vector <Point>& a) {  
  20.       if (a.size() == 1) {  
  21.             return {};  
  22.       }  
  23.       sort(a.begin(), a.end(), &cmp);  
  24.       Point p1 = a[0];  
  25.       Point p2 = a.back();  
  26.       vector <Point> up;  
  27.       vector <Point> down;  
  28.       up.push_back(p1);  
  29.       down.push_back(p1);  
  30.       for (int i = 1; i < (int)a.size(); i++) {  
  31.             if (i == a.size() - 1 || cw(p1, a[i], p2)) {  
  32.                   while (up.size() >= 2 && !cw(up[up.size()-2], up[up.size()-1], a[i])) {  
  33.                         up.pop_back();  
  34.                   }  
  35.                   up.push_back(a[i]);  
  36.             }  
  37.             if (i == a.size() - 1 || ccw(p1, a[i], p2)) {  
  38.                   while(down.size() >= 2 && !ccw(down[down.size()-2], down[down.size()-1], a[i])) {  
  39.                         down.pop_back();  
  40.                   }  
  41.                   down.push_back(a[i]);  
  42.             }  
  43.       }  
  44.       vector <Point> hull;  
  45.       for (int i = 0; i < (int)up.size(); i++) {  
  46.             hull.push_back(up[i]);  
  47.       }  
  48.       for (int i = down.size() - 2; i > 0; i--) {  
  49.             hull.push_back(down[i]);  
  50.       }  
  51.       return hull;  
  52. }  

Sunday, July 28, 2019

[Template] Segment Tree Lazy Propagation

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Algorithm         : Segment Tree Lazy Propagation
Source            : 
Category          : 
Algorithm         : 
Verdict           : Tested

struct data
{
      ll sum;
      data() : sum(0) {}
};
 
ll store[Max];
 
struct SegTree
{
      int N;
      vector <data> st;
      vector <bool> cLazy;
      vector <ll> lazy;
 
      void init(int n)
      {
            N = n;
            st.resize(4 * N + 5);
            cLazy.resize(4 * N + 5);
            lazy.resize(4 * N + 5);
      }
      void merge(data &cur, data &l, data &r)
      {
            cur.sum = (l.sum + r.sum) % mod;
      }
      void propagate(int node, int L, int R)
      {
            if (L != R)
            {
                  int lft = node * 2;
                  int rgt = lft + 1;
                  cLazy[lft] = 1;
                  cLazy[rgt] = 1;
                  lazy[lft] = (lazy[lft] + lazy[node]) % mod;
                  lazy[rgt] = (lazy[rgt] + lazy[node]) % mod;
            }
            st[node].sum = (st[node].sum + lazy[node]) % mod;
            cLazy[node] = 0;
            lazy[node] = 0;
      }
      void build(int node, int L, int R)
      {
            if (L == R)
            {
                  st[node].sum = store[L];
                  cLazy[node] = 0;
                  lazy[node] = 0;
                  return;
            }
            int lft = node * 2;
            int rgt = lft + 1;
            int M = (L + R) / 2;
            build(lft, L, M);
            build(rgt, M + 1, R);
            merge(st[node], st[lft], st[rgt]);
      }
      data Query(int node, int L, int R, int i, int j)
      {
            if (cLazy[node]) propagate(node, L, R);
            if (j < L || i > R) return data();
            if (i <= L && R <= j) return st[node];
            int lft = node * 2;
            int rgt = lft + 1;
            int M = (L + R) / 2;
            data p = Query(lft, L, M, i, j);
            data q = Query(rgt, M + 1, R, i, j);
            data cur;
            merge(cur, p, q);
            return cur;
      }
      data pQuery(int node, int L, int R, int pos)
      {
            if (cLazy[node]) propagate(node, L, R);
            if (L == R) return st[node];
            int lft = node * 2;
            int rgt = lft + 1;
            int M = (L + R) / 2;
            if (pos <= M) return pQuery(lft, L, M, pos);
            else return pQuery(rgt, M + 1, R, pos);
      }
      void update(int node, int L, int R, int i, int j, ll val)
      {
            if (cLazy[node]) propagate(node, L, R);
            if (j < L || i > R) return;
            if (i <= L && R <= j)
            {
                  cLazy[node] = 1;
                  lazy[node] = (lazy[node] + val) % mod;
                  propagate(node, L, R);
                  return;
            }
            int lft = node * 2;
            int rgt = lft + 1;
            int M = (L + R) / 2;
            update(lft, L, M, i, j, val);
            update(rgt, M+1, R, i, j, val);
            merge(st[node], st[lft], st[rgt]);
      }
      void pUpdate(int node, int L, int R, int pos, ll val)
      {
            if (cLazy[node]) propagate(node, L, R);
            if (L == R)
            {
                  cLazy[node] = 1;
                  lazy[node] = (lazy[node] + val) % mod;
                  propagate(node, L, R);
                  return;
            }
            int lft = node * 2;
            int rgt = lft + 1;
            int M = (L + R) / 2;
            if (pos <= M) pUpdate(lft, L, M, pos, val);
            else pUpdate(rgt, M+1, R, pos, val);
            merge(st[node], st[lft], st[rgt]);
      }
      data query(int pos)
      {
            return pQuery(1, 1, N, pos);
      }
      data query(int l, int r)
      {
            return Query(1, 1, N, l, r);
      }
      void update(int pos, ll val)
      {
            pUpdate(1, 1, N, pos, val);
      }
      void update(int l, int r, ll val)
      {
            update(1, 1, N, l, r, val);
      }
};

[Codemarshal] F. Find the Substrings

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : F. Find the Substrings
Source            : Codemarshal
                    ACM-ICPC 2018 Preliminary
Category          : String, Data Structure
Algorithm         : Suffix Automata, Number of distinct substring
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2. using namespace std;  
  3.   
  4. #define ll            long long int  
  5. #define endl          '\n'  
  6.   
  7. static const int maxn = 1e6 + 5;  
  8. static const ll mod = 1e9 + 7;  
  9. static const int Max = 1e6 + 7;  
  10.   
  11. int N;  
  12. ll Tree[maxn];  
  13.   
  14. ll add(ll a, ll b)  
  15. {  
  16.       a = (a + b + mod) % mod;  
  17.       return a;  
  18. }  
  19.   
  20. void update(int pos, ll val)  
  21. {  
  22.       while (pos <= N)  
  23.       {  
  24.             Tree[pos] = add(Tree[pos], val);  
  25.             pos += (pos & -pos);  
  26.       }  
  27. }  
  28.   
  29. void rangeUpdate(int l, int r, ll val)  
  30. {  
  31.       update(l, val);  
  32.       update(r + 1, -val);  
  33. }  
  34.   
  35. ll query(int pos)  
  36. {  
  37.       ll sum = 0;  
  38.       while (pos > 0)  
  39.       {  
  40.             sum = add(sum, Tree[pos]);  
  41.             pos -= (pos & -pos);  
  42.       }  
  43.       return sum;  
  44. }  
  45.   
  46. struct state  
  47. {  
  48.       int len, link;  
  49.       map <charint> next;  
  50. } st[Max * 2];  
  51.   
  52. int sz, last;  
  53.   
  54. void init()  
  55. {  
  56.       sz = last = 0;  
  57.       st[0].len = 0;  
  58.       st[0].link = -1;  
  59.       st[0].next.clear();  
  60.       for (int i = 1; i < Max * 2; i++)  
  61.       {  
  62.             st[i].len = 0;  
  63.             st[i].link = 0;  
  64.             st[i].next.clear();  
  65.       }  
  66.       ++sz;  
  67. }  
  68.   
  69. void szExtend(char c)  
  70. {  
  71.       int l, r;  
  72.       int cur = sz++;  
  73.       st[cur].len = st[last].len + 1;  
  74.       int p;  
  75.       for (p = last; p != -1 && !st[p].next.count(c); p = st[p].link)  
  76.       {  
  77.             st[p].next[c] = cur;  
  78.       }  
  79.       if (p == -1)  
  80.       {  
  81.             st[cur].link = 0;  
  82.       }  
  83.       else  
  84.       {  
  85.             int q = st[p].next[c];  
  86.             if (st[p].len + 1 == st[q].len)  
  87.             {  
  88.                   st[cur].link = q;  
  89.             }  
  90.             else  
  91.             {  
  92.                   int clone = sz++;  
  93.                   st[clone].len = st[p].len + 1;  
  94.                   st[clone].next = st[q].next;  
  95.                   st[clone].link = st[q].link;  
  96.                   for ( ; p != -1 && st[p].next[c] == q; p = st[p].link)  
  97.                   {  
  98.                         st[p].next[c] = clone;  
  99.                   }  
  100.                   l = st[ st[q].link ].len;  
  101.                   r = st[q].len;  
  102.                   assert(l+1 <= r);  
  103.                   rangeUpdate(l+1, r, -1);  
  104.                   st[q].link = st[cur].link = clone;  
  105.                   l = st[ st[q].link ].len;  
  106.                   r = st[q].len;  
  107.                   assert(l+1 <= r);  
  108.                   rangeUpdate(l+1, r, 1);  
  109.                   l = st[ st[clone].link ].len;  
  110.                   r = st[clone].len;  
  111.                   assert(l+1 <= r);  
  112.                   rangeUpdate(l+1, r, 1);  
  113.             }  
  114.       }  
  115.       l = st[ st[cur].link ].len;  
  116.       r = st[cur].len;  
  117.       assert(l+1 <= r);  
  118.       rangeUpdate(l+1, r, 1);  
  119.       last = cur;  
  120. }  
  121.   
  122. ll power[Max];  
  123. ll powerSum[Max];  
  124. ll sum[Max];  
  125. ll cumsum[Max];  
  126.   
  127. int main()  
  128. {  
  129.       ios_base::sync_with_stdio(false);  
  130.       cin.tie(nullptr);  
  131.       cout.tie(nullptr);  
  132.       cout << fixed << setprecision(12);  
  133.   
  134. //      #ifndef ONLINE_JUDGE  
  135. //            freopen("in.txt", "r", stdin);  
  136. //      #endif // ONLINE_JUDGE  
  137.   
  138.       power[0] = 1LL;  
  139.       powerSum[0] = 0LL;  
  140.       for (int i = 1; i < Max; i++)  
  141.       {  
  142.             power[i] = (power[i-1] * 26) % mod;  
  143.             powerSum[i] = (powerSum[i-1] + power[i]) % mod;  
  144.       }  
  145.   
  146.       int tc;  
  147.       cin >> tc;  
  148.       for (int tcase = 1; tcase <= tc; tcase++)  
  149.       {  
  150.             string s;  
  151.             cin >> s;  
  152.             int len = s.size();  
  153.             N = len;  
  154.             init();  
  155.             for (char ch : s) szExtend(ch);  
  156.             for (int i = 1; i <= len; i++)  
  157.             {  
  158.                   sum[i] = query(i);  
  159.                   cumsum[i] = add(cumsum[i-1], sum[i]);  
  160.             }  
  161.             cout << "Case " << tcase << ":" << endl;  
  162.             int q;  
  163.             cin >> q;  
  164.             while (q--)  
  165.             {  
  166.                   int l, r;  
  167.                   cin >> l >> r;  
  168.                   ll tsub = (powerSum[r] - powerSum[l-1] + mod) % mod;  
  169.                   ll dsub = (cumsum[r] - cumsum[l-1] + mod) % mod;  
  170.                   ll ans = (tsub - dsub + mod) % mod;  
  171.                   cout << ans << endl;  
  172.             }  
  173.             for (int i = 0; i <= N; i++) Tree[i] = 0;  
  174.       }  
  175. }