Tuesday, September 21, 2021

Codeforces ITMO Academy: pilot course » Segment Tree

<<Point Update/Range Query>>

[PART:1, STEP:1]

 A. Segment Tree for the Sum (Point Set Update/Range Sum Query)

https://codeforces.com/edu/course/2/lesson/4/1/practice/contest/273169/problem/A

B. Segment Tree for the Minimum (Point Set Update/Range Min Query)

https://codeforces.com/edu/course/2/lesson/4/1/practice/contest/273169/problem/B

C. Number of Minimums on a Segment (Point Set Update/Range Min&Count Query)

https://codeforces.com/edu/course/2/lesson/4/1/practice/contest/273169/problem/C


[PART:1, STEP:2]

A. Segment with the Maximum Sum (Point Set Update/Range Max Sum Query)

https://codeforces.com/edu/course/2/lesson/4/2/practice/contest/273278/problem/A

B. K-th one (Point Set Update/Range Sum Query/Binary Search)

https://codeforces.com/edu/course/2/lesson/4/2/practice/contest/273278/problem/B

C. First element at least X (Point Set Update/Range Max Query/Binary Search)

https://codeforces.com/edu/course/2/lesson/4/2/practice/contest/273278/problem/C

D. First element at least X-2 (Point Set Update/Range Max Query/Binary Search)


[PART:1, STEP:3]

A. Inversions (Point Set Update/Range Sum Query/Inversion)

https://codeforces.com/edu/course/2/lesson/4/3/practice/contest/274545/problem/A

B. Inversions 2 (Point Set Update/Range Sum Query/Binary Search/Kth from right)

https://codeforces.com/edu/course/2/lesson/4/3/practice/contest/274545/problem/B

C. Nested Segments (Point Set Update/Range Sum Query/Nested)

https://codeforces.com/edu/course/2/lesson/4/3/practice/contest/274545/problem/C

D. Intersecting Segments  (Point Set Update/Range Sum Query/Intersection)

E. Addition to Segment (Point Add Update/Range Sum Query/imos)

https://codeforces.com/edu/course/2/lesson/4/3/practice/contest/274545/problem/E


[PART:1, STEP:4]

A. Sign alternation (Point Set Update/Range Sum Query/Alternate Sign)

https://codeforces.com/edu/course/2/lesson/4/4/practice/contest/274684/problem/A

B. Cryptography (Point Set Update/Range Matrix Multi Query)

https://codeforces.com/edu/course/2/lesson/4/4/practice/contest/274684/problem/B

C. Number of Inversions on Segment (Point Set Update/Range Inverse Number Query)

https://codeforces.com/edu/course/2/lesson/4/4/practice/contest/274684/problem/C

D. Number of Different on Segment (Point Set Update/Range Bitwise OR Query)

https://codeforces.com/edu/course/2/lesson/4/4/practice/contest/274684/problem/D

E. Earthquakes (Point Set Update/Range Min Query with Range Update)

https://codeforces.com/edu/course/2/lesson/4/4/practice/contest/274684/problem/E


<<Range Update/Point Query>>

[PART:2, STEP:1]

A. Addition to Segment (Range Add Update/Point Get Query)

https://codeforces.com/edu/course/2/lesson/5/1/practice/contest/279634/problem/A

B. Applying MAX to Segment (Range Max Update/Point Get Query)


C. Assignment to Segment (Range Set Update/Point Get Query)

https://codeforces.com/edu/course/2/lesson/5/1/practice/contest/279634/problem/C

[PART:2, STEP:4]

B. Add Arithmetic Progression On Segment (Range Add-Multi Update/Point Get Query)

https://codeforces.com/edu/course/2/lesson/5/4/practice/contest/280801/problem/B

E. Wall (Range MinMax Update/Point Get Query)

https://codeforces.com/edu/course/2/lesson/5/4/practice/contest/280801/problem/E


<<Range Update/Range Query>>

[PART:2, STEP:2]

A. Addition and Minimum (Range Add Update/Range Min Query)

https://codeforces.com/edu/course/2/lesson/5/2/practice/contest/279653/problem/A

B. Multiplication and Sum (Range Multi Update/Range Sum Query)

https://codeforces.com/edu/course/2/lesson/5/2/practice/contest/279653/problem/B

C. Bitwise OR and AND (Range OR Update/Range AND Query)

https://codeforces.com/edu/course/2/lesson/5/2/practice/contest/279653/problem/C

D. Addition and Sum (Range Add Update/Range Sum Query)

https://codeforces.com/edu/course/2/lesson/5/2/practice/contest/279653/problem/D

E. Assignment and Minimum (Range Set Update/Range Min Query)

https://codeforces.com/edu/course/2/lesson/5/2/practice/contest/279653/problem/E

F. Assignment and Sum (Range Set Update/Range Sum Query)

https://codeforces.com/edu/course/2/lesson/5/2/practice/contest/279653/problem/F


[PART:2, STEP:3]

A. Assignment and Maximal Segment (Range Set Update/Range MaxSumSeg Query)

https://codeforces.com/edu/course/2/lesson/5/3/practice/contest/280799/problem/A

B. Inverse and K-th one (Range Inverse Update/Range Sum Query/Binary Search)

https://codeforces.com/edu/course/2/lesson/5/3/practice/contest/280799/problem/B

C. Addition and First element at least X (Range Add Update/Range Max Query/Binary Search)

https://codeforces.com/edu/course/2/lesson/5/3/practice/contest/280799/problem/C


[PART:2, STEP:4]

A. Assignment, Addition, and Sum (Range Set Update/Range Add Update/Range Sum Query)

https://codeforces.com/edu/course/2/lesson/5/4/practice/contest/280801/problem/A

C. Painter (Range ColorSegment Update/Range CountSegment Query)

https://codeforces.com/edu/course/2/lesson/5/4/practice/contest/280801/problem/C

D. Problem About Weighted Sum (Range Add Update/Range Weighted Sum Query)

https://codeforces.com/edu/course/2/lesson/5/4/practice/contest/280801/problem/D

F. Mountain (Range Set Update/Range Sum Query/Range Max Query/Binary Search)

https://codeforces.com/edu/course/2/lesson/5/4/practice/contest/280801/problem/F

Friday, September 17, 2021

Two Pointers Problems in Leetcode

 1.Running from both ends of an array







 - 2 Sum problem

3Sum - LeetCode

 - Trapping Water 
Container With Most Water - LeetCode

Trapping Rain Water - LeetCode


 - Next Permutation

Next Permutation - LeetCode

Next Greater Element III - LeetCode

Minimum Adjacent Swaps to Reach the Kth Smallest Number - LeetCode


 - Reversing / Swapping

Valid Palindrome - LeetCode

Reverse String - LeetCode

Reverse Vowels of a String - LeetCode

Valid Palindrome II - LeetCode

Reverse Only Letters - LeetCode

Remove Element - LeetCode


 - Others

Bag of Tokens - LeetCode

DI String Match - LeetCode

Minimum Length of String After Deleting Similar Ends - LeetCode

Sentence Similarity III - LeetCode

Find K Closest Elements - LeetCode

Shortest Distance to a Character - LeetCode



2.Slow & Fast Pointers





 


 

 - Linked List Operations

Linked List Cycle - LeetCode

Linked List Cycle II - LeetCode

Remove Nth Node From End of List - LeetCode

Rotate List - LeetCode

Reorder List - LeetCode


 - Cyclic Detection

Find the Duplicate Number - LeetCode

Circular Array Loop - LeetCode


 - Sliding Window Like

Number of Subarrays with Bounded Maximum - LeetCode


 - String

String Compression - LeetCode


 - Remove Duplicate


 - Others

Statistics from a Large Sample - LeetCode

Partition Labels - LeetCode

Magical String - LeetCode

Friends Of Appropriate Ages - LeetCode

Longest Mountain in Array - LeetCode

Shortest Subarray to be Removed to Make Array Sorted - LeetCode


3.Running from beginning of 2 arrays / Merging 2 arrays









  - Sorted arrays

Merge Sorted Array - LeetCode


 - Intersection / LCA like

Intersection of Two Linked Lists - LeetCode 

Intersection of Two Arrays - LeetCode


 - Median Finder

 - Meet-in-the-middle / Binary Search


 - Others

Shortest Unsorted Continuous Subarray - LeetCode

Most Profit Assigning Work - LeetCode

Largest Merge Of Two Strings - LeetCode

Swap Adjacent in LR String - LeetCode


4.Split & Merge of an array / Divide & Conquer










 


 - Partition 

Partition List - LeetCode

 - Sorting

Sort List - LeetCode

Monday, May 31, 2021

Segment Tree problems in Atcoder

A. Segment Trees

1.Range Add Update/Point Get Query
D - ぴょんぴょんトレーニング (atcoder.jp)
typhoon - 台風 (Typhoon) (atcoder.jp)



2.Range Min Query/Point Update
D - 括弧列 (atcoder.jp)



3.


4.


5.


6.


B. Segment Tree with Lazy Propagation

1.Range Add/Range Min Query
B - ドキドキデート大作戦高橋君 (atcoder.jp)

2.Range Set/Range Max Query
029 - Long Bricks(★5) (atcoder.jp)

3.Range Set/Range Sum Query + Digit Arrange
E - Replace Digits (atcoder.jp)

4.Range Add/Range Max Query (Inline DP)
W - Intervals (atcoder.jp)

5.Range Multi&Add/Range Sum Query
K - Range Affine Range Sum (atcoder.jp)

6.Range Add/Range Sum Query (2D Rectangles)
N - ビルの建設 (atcoder.jp)

7.Range Min Update/Range Min Query
F - Simplified Reversi (atcoder.jp)

8.Range Inverse Update/Range Inverse Count Query (Binary string)
L - Lazy Segment Tree (atcoder.jp)

9.

10.

11.


C. Some extras

1.Range Set/Range Or Query (Flatten Trees by Euler Tour, Segtee on Tree)
E. New Year Tree: Problem - E - Codeforces

2.

3.





Sunday, March 21, 2021

POJ.2186 Popular Cows

1.Problem
2186 -- Popular Cows (poj.org)

2.Idea
SCC+Topological Sort

3.Source

 const int N = 100005;  
 //////////////////////////////  
 int V;  
 vector<int> G[N];  
 vector<int> rG[N];  
 vector<int> vs;  
 bool used[N];  
 int cmp[N];  
 void add_edge(int from, int to)  
 {  
      G[from].push_back(to);  
      rG[to].push_back(from);  
 }  
 void dfs(int v)  
 {  
      used[v] = true;  
      for (int i = 0; i < G[v].size(); i++) {  
           if (!used[G[v][i]]) dfs(G[v][i]);  
      }  
      vs.push_back(v);  
 }  
 void rdfs(int v, int k)  
 {  
      used[v] = true;  
      cmp[v] = k;  
      for (int i = 0; i < rG[v].size(); i++) {  
           if (!used[rG[v][i]]) rdfs(rG[v][i], k);  
      }  
 }  
 int scc()  
 {  
      memset(used, 0, sizeof used);  
      vs.clear();  
      for (int v = 0; v < V; v++) {  
           if (!used[v]) dfs(v);  
      }  
      memset(used, 0, sizeof used);  
      int k = 0;  
      for (int i = vs.size() - 1; i >= 0; i--) {  
           if (!used[vs[i]]) rdfs(vs[i], k++);  
      }  
      return k;  
 }  
 int n, m;  
 int a[N], b[N];  
 void solve()  
 {  
      scanf("%d%d", &n, &m);  
      REP(i, m) scanf("%d%d", &a[i], &b[i]);  
      V = n;  
      for (int i = 0; i < m; i++) {  
           add_edge(a[i] - 1, b[i] - 1);  
      }  
      int nn = scc();  
      int u = 0, num = 0;  
      for (int v = 0; v < V; v++) {  
           if (cmp[v] == nn - 1) {  
                u = v;  
                num++;  
           }  
      }  
      memset(used, 0, sizeof(used));  
      rdfs(u, 0);  
      for (int v = 0; v < V; v++) {  
           if (!used[v]) {  
                num = 0;  
                break;  
           }  
      }  
      printf("%d\n", num);  
 }  

Atcoder.abc185_f F - Range Xor Query

1.Problem
F - Range Xor Query (atcoder.jp)

2.Idea
XOR segtree

3.Source

 Int seg[1 << 20];  
 void set_value(Int pos, Int val) {  
      pos += 1 << 19;  
      seg[pos] = seg[pos] ^ val;  
      while ((pos /= 2) > 0) {  
           seg[pos] = seg[pos * 2] ^ seg[pos * 2 + 1];  
      }  
 }  
 Int get_xor(int ql, int qr, int sl = 0, int sr = 1 << 19, int pos = 1) {  
      //no overlap  
      if (qr <= sl || sr <= ql) return 0;  
      //fit in the segment  
      if (ql <= sl && sr <= qr) return seg[pos];  
      //partially overlap  
      Int sm = (sl + sr) / 2;  
      Int lxor = get_xor(ql, qr, sl, sm, pos * 2);  
      Int rxor = get_xor(ql, qr, sm, sr, pos * 2 + 1);  
      return lxor ^ rxor;  
 }  
 void solve()  
 {  
      Int n, q, t, x, y;  
      cin >> n >> q;  
      for (int i = 0; i < n; i++) {  
           int x; cin >> x;  
           set_value(i, x);  
      }  
      for (int i = 0; i < q; i++) {  
           cin >> t >> x >> y;  
           if (t == 1) {  
                set_value(x - 1, y);  
           }  
           else {  
                cout << get_xor(x - 1, y) << endl;  
           }  
      }  
 }  

Monday, March 1, 2021

LeetCode.699 Falling Squares

1.Problem
Falling Squares - LeetCode

2.Idea
Using range max query on segtree

3.Source

 class Solution {  
 public:  
      map<int, int> mp;  
      int tree[8000];  
      void update(int t, int low, int high, int i, int j, int h) {  
           if (i > j) return;  
           if (low == high) {  
                tree[t] = h;  
                return;  
           }  
           int mid = (low + high) / 2;  
           update(2 * t, low, mid, i, min(mid, j), h);  
           update(2 * t + 1, mid + 1, high, max(mid + 1, i), j, h);  
           tree[t] = max(tree[2 * t], tree[2 * t + 1]);  
      }  
      int query(int t, int low, int high, int i, int j) {  
           if (i > j) return -2e9;  
           if (low == i && high == j) return tree[t];  
           int mid = (low + high) / 2;  
           return max(  
                query(2 * t, low, mid, i, min(mid, j)),  
                query(2 * t + 1, mid + 1, high, max(mid + 1, i), j)  
           );  
      }  
      vector<int> fallingSquares(vector<vector<int>>& positions) {  
           set<int> s;  
           memset(tree, 0, sizeof(tree));  
           for (auto it : positions) {  
                s.insert(it[0]);  
                s.insert(it[0] + it[1] - 1);  
           }  
           int compressed = 1, n = positions.size();  
           vector<int> ans(n);  
           for (auto it : s)  
                mp[it] = compressed++;  
           for(int i=0; i<n; i++){  
       int start=positions[i][0], end=positions[i][1]+start-1, h=positions[i][1];  
       int curr=query(1, 1, 2*n, mp[start], mp[end]), ncurr=curr+h;  
       update(1, 1, 2*n, mp[start], mp[end], ncurr);  
       ans[i]=tree[1];  
     }  
           return ans;  
      }  
 };  

Saturday, February 6, 2021

Atcoder.arc068_c Snuke Line

1.Problem
https://atcoder.jp/contests/arc068/tasks/arc068_c

2.Idea
Using BIT like an imos method in order to update intervals.

3.Source

 class BIT { //1 -indexed  
      const int n;  
      vector<Int> bit;  
 public:  
      BIT(int _n = 0) : n(_n), bit(n + 1, 0) {}  
      void add(int i, const Int x = 1) { for (i++; i <= n; i += i&-i) bit[i] += x; }  
      Int sum(int i) { Int x = 0; for (i++; i; i -= i & -i) x += bit[i]; return x; }  
      Int sum(int i, int j) { return sum(j) - sum(i - 1); }  
 };  
 vector<pair<int, int>> range[N];  
 void solve()  
 {  
      int n, m;  
      cin >> n >> m;  
      REP(i, n) {  
           int l, r; cin >> l >> r; 
           // Holding the intervals by the length 
           range[r - l + 1].push_back(make_pair(l, r));  
      }  
      BIT bit(m + 1);  
      int up = n;  
      RREP(d, m) {  
           for (pair<int, int> p : range[d]) {  
                // Here is the imos in interval
                bit.add(p.first, 1);  
                bit.add(p.second + 1, -1);  
                up--;  
           }  
           int cnt = 0;  
           // This takes only log(d)
           for (int i = d; i <= m; i += d) {  
                cnt += bit.sum(i);  
           }  
           cout << cnt + up << endl;  
      }  
 }  

Thursday, February 4, 2021

Atcoder.abc127_f Absolute Minima

1.Problem
https://atcoder.jp/contests/abc127/submissions/5607909

2.Idea
Using BIT to find and calc the median value.
Credit

3.Source

 const int N = 200005;  
 //////////////////////////////  
 template<typename T>  
 struct BIT {  
      int n;  
      vector<T> dat;  
      BIT(int n = 0) {  
           initialize(n);  
      }  
      void initialize(int nin) {  
           n = nin;  
           dat.resize(n);  
           for (int i = 0; i<n; i++) dat[i] = 0;  
      }  
      T sum(int i) {  
           T s = 0;  
           while (i >= 0) {  
                s += dat[i];  
                i = (i & (i + 1)) - 1;  
           }  
           return s;  
      }  
      T sum_between(int i, int j) {  
           if (i > j) return 0;  
           return sum(j) - sum(i - 1);  
      }  
      void plus(int i, T x) {  
           while (i < n) {  
                dat[i] += x;  
                i |= i + 1;  
           }  
      }  
      // a[0]+...+a[ret] >= x  
      int lower_bound(T x) {  
           int ret = -1;  
           int k = 1;  
           while (2 * k <= n) k <<= 1;  
           for (; k>0; k >>= 1) {  
                if (ret + k < n && dat[ret + k] < x) {  
                     x -= dat[ret + k];  
                     ret += k;  
                }  
           }  
           return ret + 1;  
      }  
 };  
 Int T[N], A[N], B[N];  
 void solve()  
 {  
      int q;  
      cin >> q;  
      vector<int> as;  
      REP(i, q) {  
           cin >> T[i];  
           if (T[i] == 1) {  
                cin >> A[i] >> B[i];  
                as.push_back(A[i]);  
           }  
      }  
      sort(as.begin(), as.end());  
      as.erase(unique(as.begin(), as.end()), as.end());  
      map<int, int> mp;  
      int sz = as.size();  
      REP(i, sz) mp[as[i]] = i;  
      BIT<Int> bitnum(sz);  
      BIT<Int> bitsum(sz);  
      Int fix = 0;  
      int all = 0;  
      REP(i, q) {  
           if (T[i] == 1) {  
                int a = mp[A[i]];  
                bitsum.plus(a, A[i]);  
                bitnum.plus(a, 1);  
                fix += B[i];  
                all++;  
           }  
           else {  
                Int ans = fix;  
                int idx = bitnum.lower_bound((all + 1) / 2);  
                ans += bitsum.sum_between(idx + 1, sz - 1);  
                ans -= as[idx] * bitnum.sum_between(idx + 1, sz - 1);  
                ans -= bitsum.sum_between(0, idx - 1);  
                ans += as[idx] * bitnum.sum_between(0, idx - 1);  
                cout << as[idx] << " " << ans << endl;  
           }  
      }  
 }   

Sunday, January 24, 2021

Atcoder.chokudai_S001_h LIS

1.Problem
https://atcoder.jp/contests/chokudai_S001/tasks/chokudai_S001_h

2.Idea
Using BIT Max Range Query

3.Source

 const int N = 100005;  
 //////////////////////////////  
 class BIT {  //1 -indexed
      const int n;  
      vector<Int> bit;  
 public:  
      BIT(int _n = 0) : n(_n), bit(n + 1, 0) {}  
      void add(int i, const Int x = 1) { for (i++; i <= n; i += i&-i) bit[i] += x; }  
      Int sum(int i) { Int x = 0; for (i++; i; i -= i & -i) x += bit[i]; return x; }  
      Int sum(int i, int j) { return sum(j) - sum(i - 1); }  
 };  
 struct FenwickTreeMin {  
      vector<int> bit;  //0 -indexed
      int n;  
      const int INF = (int)1e9;  
      FenwickTreeMin(int n) {  
           this->n = n;  
           bit.assign(n, INF);  
      }  
      FenwickTreeMin(vector<int> a) : FenwickTreeMin(a.size()) {  
           for (size_t i = 0; i < a.size(); i++)  
                update(i, a[i]);  
      }  
      int getmin(int r) {  
           int ret = INF;  
           for (; r >= 0; r = (r & (r + 1)) - 1)  
                ret = min(ret, bit[r]);  
           return ret;  
      }  
      void update(int idx, int val) {  
           for (; idx < n; idx = idx | (idx + 1))  
                bit[idx] = min(bit[idx], val);  
      }  
 };  
 struct FenwickTreeMax {  
      vector<int> bit;  // 0 - indexed
      int n;  
      FenwickTreeMax(int n) {  
           this->n = n;  
           bit.assign(n, -INF);  
      }  
      FenwickTreeMax(vector<int> a) : FenwickTreeMax(a.size()) {  
           for (size_t i = 0; i < a.size(); i++)  
                update(i, a[i]);  
      }  
      int getMax(int r) {  
           int ret = -INF;  
           for (; r >= 0; r = (r & (r + 1)) - 1)  
                ret = max(ret, bit[r]);  
           return ret;  
      }  
      void update(int idx, int val) {  
           for (; idx < n; idx = idx | (idx + 1))  
                bit[idx] = max(bit[idx], val);  
      }  
 };  
 int n;  
 int a[N];  
 void solve()  
 {  
      cin >> n;  
      REP(i, n) cin >> a[i];  
      map<int, int> mp;  
      REP(i, n) mp[a[i]] = 0;  
      int i = 0;  
      for (auto it = mp.begin(); it != mp.end(); it++) {  
           it->second = i;  
           i++;  
      }  
      FenwickTreeMax ftm(n);  
      REP(i, n) {  
           int cur = mp[a[i]];  
           int tmp = ftm.getMax(cur - 1);  
           if(tmp == -INF) ftm.update(cur, 1);  
           else ftm.update(cur, tmp + 1);  
      }  
      cout << ftm.getMax(n - 1) << endl;  
 }