├── .gitignore ├── README.md ├── bit.cpp ├── floyd_warshall.cpp ├── getting_primefactors.cpp ├── modular_operations.cpp ├── palindrome.cpp ├── DSU.cpp ├── DSU2.cpp ├── fraction.cpp ├── rolling_hash.cpp ├── range_module.cpp ├── bridges_articulation_points.cpp ├── sparse_segment_tree_class.cpp ├── bitset.cpp ├── matrix_struct.cpp ├── segment_tree.cpp ├── segment_tree_class.cpp ├── template.cpp ├── combination.cpp └── sparse_segment_tree.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | a.out 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Interviews-Competitive-Programming 2 | 3 | This contains the list of data-structures and algorithms required for interviews. 4 | 5 | Special thanks to Raghavan and his code: https://github.com/Raghavan098/competitive-programming 6 | -------------------------------------------------------------------------------- /bit.cpp: -------------------------------------------------------------------------------- 1 | struct bit{ // use 0 based indices!!! 2 | int n; vector tree; 3 | bit(int n) : n(n) { tree.assign(n + 1, 0); } 4 | int query(int l, int r) { return query(r) - query(l - 1); } 5 | int query(int r) { 6 | int ans = 0; 7 | for(r++; r; r -= r&(-r)) ans+=tree[r]; 8 | return ans; 9 | } 10 | void update(int i, int v) { 11 | for(i++; i <= n; i+= i&(-i)) tree[i]+=v; 12 | } 13 | void assign(int i, int v) { 14 | update(i, v - query(i, i)); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /floyd_warshall.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); 4 | typedef long long llt; 5 | typedef long double lld; 6 | using namespace std; 7 | 8 | int graph[500][500]; 9 | int shortest_path[500][500]; 10 | int n; 11 | 12 | void floyd_warshall(){ 13 | for(int i=0;i 2 | #include 3 | #define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); 4 | #define pb push_back 5 | #define MAXN 10000 6 | typedef long long llt; 7 | typedef long double lld; 8 | using namespace std; 9 | 10 | 11 | int n; 12 | int spf[MAXN]; 13 | void sieve() 14 | { 15 | spf[1] = 1; 16 | for (int i=2; i getFactorization(int x) 33 | { 34 | vector ret; 35 | while (x != 1) 36 | { 37 | ret.push_back(spf[x]); 38 | x = x / spf[x]; 39 | } 40 | return ret; 41 | } 42 | -------------------------------------------------------------------------------- /modular_operations.cpp: -------------------------------------------------------------------------------- 1 | ll mult(ll a, ll b, ll mod) 2 | { 3 | ll res = 0; 4 | a %= mod; 5 | while (b) 6 | { 7 | if (b & 1) 8 | res = (res + a) % mod; 9 | a = (2 * a) % mod; 10 | b >>= 1; 11 | } 12 | return res; 13 | } 14 | 15 | 16 | 17 | int power(int x, int t){ 18 | int ans = 1; 19 | while(t > 0) { 20 | if(t & 1) ans = 1LL * ans * x % MOD; 21 | x = 1LL * x * x % MOD; 22 | t >>= 1; 23 | } 24 | return ans; 25 | } 26 | inline int sub(int a, int b){ 27 | a %= MOD; 28 | b %= MOD; 29 | a = ((a - b) % MOD + MOD) % MOD; 30 | return a; 31 | } 32 | 33 | inline int add(int a, int b){ 34 | a %= MOD; 35 | b %= MOD; 36 | a = (a + b) % MOD; 37 | return a; 38 | } 39 | 40 | inline int mul(int a, int b){ 41 | a %= MOD; 42 | b %= MOD; 43 | a = (a * b) % MOD; 44 | return a; 45 | } 46 | 47 | inline int inv(int a){ 48 | a = a % MOD; 49 | a = power(a, MOD - 2); 50 | return a; 51 | } 52 | -------------------------------------------------------------------------------- /palindrome.cpp: -------------------------------------------------------------------------------- 1 | 2 | typedef long long int ll; 3 | 4 | 5 | struct RollingHash{ 6 | vector pwr, hsh; 7 | ll A, M; 8 | int n; 9 | 10 | RollingHash(){} 11 | 12 | RollingHash(string s, ll _A = 31, ll _M = 1e9 + 7){ 13 | n = s.size(); 14 | pwr.resize(n+1); hsh.resize(n+1); 15 | 16 | A = _A, M = _M; 17 | 18 | pwr[0] = 1; 19 | for(int i = 1; i <= n; i++) pwr[i] = pwr[i-1] * A % M; 20 | 21 | hsh[0] = s[0] % M + 1; 22 | for(int i = 1; i < n; i++){ 23 | hsh[i] = (hsh[i - 1] * A % M) + s[i] + 1; if(hsh[i] >= M) hsh[i] -= M; 24 | } 25 | } 26 | 27 | ll getHash(int x, int y){ 28 | assert(x >= 0 and x < n and y >= 0 and y <= n); 29 | return (hsh[y] + M - ((x-1 >= 0)? hsh[x-1] * pwr[y-x+1] % M : 0)) % M; 30 | } 31 | }; 32 | 33 | struct PalindromeChecker { 34 | RollingHash hash; 35 | RollingHash revHash; 36 | int n; 37 | 38 | PalindromeChecker(string s): hash(s), n(s.size()) { 39 | reverse(s.begin(), s.end()); 40 | revHash = RollingHash(s); 41 | } 42 | 43 | bool isPalindrome(int i, int j) { 44 | return hash.getHash(i, j) == revHash.getHash(n-j-1, n-i-1); 45 | } 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /DSU.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class DSU { 5 | public: 6 | 7 | int n; 8 | int setCount; 9 | vector size; 10 | vector _parent; 11 | 12 | DSU(int n): n(n), setCount(n) { 13 | 14 | for(int i = 0; i < n; i++) 15 | _parent.push_back(i); 16 | 17 | size.resize(n, 1); 18 | } 19 | 20 | int parent(int i) { 21 | if(_parent[i] == i)return i; 22 | 23 | return _parent[i] = parent(_parent[i]); 24 | } 25 | 26 | void join(int i, int j) { 27 | 28 | int set1 = parent(i); 29 | int set2 = parent(j); 30 | if(set1 == set2) return; 31 | setCount--; 32 | 33 | if(size[set1] < size[set2]) 34 | swap(set1, set2); 35 | 36 | size[set1] += size[set2]; 37 | _parent[set2] = set1; 38 | } 39 | 40 | vector> getSets() { 41 | 42 | vector> results; 43 | map> t; 44 | for(int i = 0; i < n; i++) 45 | t[parent(i)].insert(i); 46 | 47 | for (auto v: t) 48 | results.push_back(v.second); 49 | 50 | return results; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /DSU2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class DSU { 5 | public: 6 | 7 | int n; 8 | int setCount; 9 | vector> _sets; // Can be unordered_set as well 10 | vector _setIndex; 11 | 12 | DSU(int n): n(n), setCount(n) { 13 | for(int i = 0; i < n; i++) { 14 | _sets.push_back({i}); 15 | _setIndex.push_back(i); 16 | } 17 | } 18 | 19 | int setIndex(int i) { 20 | return _setIndex[i]; 21 | } 22 | 23 | set& getSet(int i) { 24 | return _sets[_setIndex[i]]; 25 | } 26 | 27 | int setSize(int i) { 28 | return getSet(i).size(); 29 | } 30 | 31 | void join(int i, int j) { 32 | 33 | if(setIndex(i) == setIndex(j))return; 34 | if(setSize(i) < setSize(j)) 35 | swap(i, j); 36 | 37 | auto &set1 = getSet(i); 38 | auto &set2 = getSet(j); 39 | 40 | int targetSetIndex = setIndex(i); 41 | 42 | set1.insert(set2.begin(), set2.end()); 43 | 44 | for(int k: set2) 45 | _setIndex[k] = targetSetIndex; 46 | 47 | setCount--; 48 | 49 | set2.clear(); 50 | } 51 | 52 | 53 | vector> getSets() { 54 | vector> results; 55 | for (auto v: _sets) 56 | if(v.size())results.push_back(v); 57 | return results; 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /fraction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int _gcd(int a, int b) { 5 | if(b==0)return a; 6 | return _gcd(b, a%b); 7 | } 8 | int gcd(int a, int b) { 9 | a = abs(a); 10 | b = abs(b); 11 | return _gcd(a, b); 12 | } 13 | 14 | struct Fraction{ 15 | int n; 16 | int d; 17 | Fraction(int _n, int _d): n(_n), d(_d) { 18 | if(d!=0) { 19 | int g = gcd(n, d); 20 | n/= g; 21 | d/= g; 22 | } 23 | } 24 | bool operator<(Fraction const &other) const { 25 | return n * other.d < other.n * d; 26 | } 27 | 28 | bool operator>(Fraction const &other) const { 29 | return other < *this; 30 | } 31 | 32 | bool operator==(Fraction const &other) const { 33 | return other.d == d && other.n == n; 34 | } 35 | 36 | Fraction add(Fraction other) { 37 | return Fraction(n * other.d + other.n * d, other.d * d); 38 | } 39 | 40 | Fraction subtract(Fraction other) { 41 | return Fraction(n * other.d - other.n * d, other.d * d); 42 | } 43 | 44 | Fraction multiply(Fraction other) { 45 | return Fraction(n * other.n , other.d * d); 46 | } 47 | 48 | Fraction divide(Fraction other) { 49 | return multiply(Fraction(other.d, other.n)); 50 | } 51 | 52 | void print() { 53 | cout << n<< " / "< pwr, hsh; 6 | ll A, M; 7 | int n; 8 | 9 | RollingHash(vector s, ll _A = 31, ll _M = 1e9 + 7) { 10 | n = s.size(); 11 | pwr.resize(n + 1); 12 | hsh.resize(n + 1); 13 | 14 | A = _A, M = _M; 15 | 16 | pwr[0] = 1; 17 | for (int i = 1; i <= n; i++) pwr[i] = pwr[i - 1] * A % M; 18 | 19 | hsh[0] = s[0] % M + 1; 20 | for (int i = 1; i < n; i++) { 21 | hsh[i] = (hsh[i - 1] * A % M) + s[i] + 1; 22 | if (hsh[i] >= M) hsh[i] -= M; 23 | } 24 | } 25 | 26 | ll getHash(int x, int y) { 27 | assert(x >= 0 and x < n and y >= 0 and y <= n); 28 | return (hsh[y] + M - ((x - 1 >= 0) ? hsh[x - 1] * pwr[y - x + 1] % M : 0)) % M; 29 | } 30 | }; 31 | 32 | struct RollingHash { 33 | vector pwr, hsh; 34 | ll A, M; 35 | int n; 36 | 37 | RollingHash(string s, ll _A = 257, ll _M = 1e9 + 7) { 38 | n = s.size(); 39 | pwr.resize(n + 1); 40 | hsh.resize(n + 1); 41 | 42 | A = _A, M = _M; 43 | 44 | pwr[0] = 1; 45 | for (int i = 1; i <= n; i++) pwr[i] = pwr[i - 1] * A % M; 46 | 47 | hsh[0] = s[0] % M + 1; 48 | for (int i = 1; i < n; i++) { 49 | hsh[i] = (hsh[i - 1] * A % M) + s[i] + 1; 50 | if (hsh[i] >= M) hsh[i] -= M; 51 | } 52 | } 53 | 54 | ll getHash(int x, int y) { 55 | assert(x >= 0 and x < n and y >= 0 and y <= n); 56 | return (hsh[y] + M - ((x - 1 >= 0) ? hsh[x - 1] * pwr[y - x + 1] % M : 0)) % M; 57 | } 58 | }; 59 | 60 | struct PalindromeChecker { 61 | RollingHash hash; 62 | RollingHash revHash; 63 | 64 | PalindromeChecker(String S) 65 | }; 66 | -------------------------------------------------------------------------------- /range_module.cpp: -------------------------------------------------------------------------------- 1 | 2 | map::iterator lower_bound2( map &mp, int key) { 3 | if(mp.empty())return mp.end(); 4 | 5 | auto it = mp.lower_bound(key); 6 | if(it->first == key) return it; 7 | 8 | if(it == mp.begin())return mp.end(); 9 | 10 | it--; 11 | return it; 12 | } 13 | 14 | // Left and Right Inclusive 15 | 16 | class RangeModule { 17 | 18 | map mp; 19 | public: 20 | RangeModule() {} 21 | 22 | void addRange(int left, int right) { 23 | removeRange(left, right); 24 | 25 | auto it = lower_bound2(mp, left); 26 | 27 | if(it!=mp.end() && it->second == left-1) 28 | left = it->first; 29 | 30 | if(mp.count(right+1)){ 31 | 32 | int t = right+1; 33 | right = mp.find(t)->second; 34 | mp.erase(t); 35 | } 36 | 37 | mp[left] = right; 38 | 39 | 40 | } 41 | 42 | bool queryRange(int left, int right) { 43 | 44 | auto it = lower_bound2(mp, left); 45 | 46 | return it!=mp.end() && it->second>=right; 47 | } 48 | 49 | void removeRange(int left, int right) { 50 | 51 | if(mp.empty())return; 52 | 53 | auto it = mp.lower_bound(left); 54 | 55 | if(it!=mp.begin()) { 56 | it--; 57 | if(it->first < left){ 58 | if(it->second >= left) { 59 | if(it->second >right) 60 | mp[right+1] = it->second; 61 | it->second = left - 1; 62 | } 63 | } 64 | it++; 65 | } 66 | 67 | while(it!= mp.end() && it->first <=right) { 68 | auto temp = it; 69 | it++; 70 | if(temp->second >right) mp[right+1] = temp->second; 71 | mp.erase(temp); 72 | } 73 | 74 | } 75 | }; 76 | 77 | /** 78 | * Your RangeModule object will be instantiated and called as such: 79 | * RangeModule* obj = new RangeModule(); 80 | * obj->addRange(left,right); 81 | * bool param_2 = obj->queryRange(left,right); 82 | * obj->removeRange(left,right); 83 | */ -------------------------------------------------------------------------------- /bridges_articulation_points.cpp: -------------------------------------------------------------------------------- 1 | // https://codeforces.com/blog/entry/71146 2 | // https://leetcode.com/problems/critical-connections-in-a-network/submissions/ 3 | // https://pastebin.com/7MWuxdLQ 4 | // https://pastebin.com/ATwq4mJa 5 | // https://codeforces.com/blog/entry/68138 (best) 6 | 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | vector articulationPoints; 13 | vector> bridges; 14 | 15 | vector> g; 16 | // Earliest ancestor I can reach by using a back edge either directly 17 | // or by going down the tree and finding a back edge 18 | vector lowestAncestorTime; 19 | vector discoveryTime; 20 | int currentTime = 0; 21 | 22 | void dfs(int u, int parent = -1) { 23 | if (discoveryTime[u]) 24 | return; // Already processed 25 | 26 | discoveryTime[u] = lowestAncestorTime[u] = ++currentTime; 27 | 28 | bool isArticulationVertex = false; 29 | int children = 0; 30 | for (int v : g[u]) { 31 | if (v == parent) 32 | continue; 33 | if (!discoveryTime[v]) { // Is Child 34 | children++; 35 | dfs(v, u); 36 | lowestAncestorTime[u] = min(lowestAncestorTime[u], lowestAncestorTime[v]); 37 | if (lowestAncestorTime[v] > discoveryTime[u]) { 38 | // Cannot reach me or above in alternate ways, so this is a bridge 39 | vector t = {u, v}; 40 | sort(t.begin(), t.end()); 41 | bridges.push_back(t); 42 | } 43 | 44 | if (lowestAncestorTime[v] >= discoveryTime[u]) { 45 | // Cannot reach above me in alternate ways, so this is an articulation vertex 46 | // Except if I am a leaf node 47 | isArticulationVertex = true; 48 | } 49 | } else { 50 | lowestAncestorTime[u] = min(lowestAncestorTime[u], discoveryTime[v]); 51 | } 52 | } 53 | if (isArticulationVertex) { 54 | if (parent != -1 || children > 1) 55 | articulationPoints.push_back(u); 56 | } 57 | } 58 | 59 | int main() { 60 | int n, m; 61 | cin >> n >> m; 62 | g.resize(n); 63 | lowestAncestorTime.resize(n); 64 | discoveryTime.resize(n); 65 | for (int i = 0; i < m; i++) { 66 | int u, v; 67 | cin >> u >> v; 68 | g[u].push_back(v); 69 | g[v].push_back(u); 70 | } 71 | dfs(0); 72 | } 73 | -------------------------------------------------------------------------------- /sparse_segment_tree_class.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/falling-squares 2 | struct segment_tree { 3 | segment_tree(long n) { 4 | int size = 1; 5 | while(size < n) { 6 | size *= 2; 7 | } 8 | this->n = size; 9 | } 10 | 11 | // [x, y) 12 | int rmq(long x, long y) { 13 | return rmq(x, y, 0, n); 14 | } 15 | 16 | // [x, y) 17 | void add(long x, long y, long val) { 18 | return add(x, y, val, 0, n); 19 | } 20 | 21 | private: 22 | 23 | unordered_map tree; 24 | unordered_map lazy; 25 | long n; 26 | 27 | int rmq(long x, long y, long l, long r, long id = 1) { 28 | if (!tree.count(id)) return 0; 29 | 30 | if (x >= r || y <= l) return 0; // fully out of range 31 | if (x <= l && r <= y) return tree[id]; // fully in range 32 | 33 | propagate(id); 34 | 35 | int m = (l + r) / 2; 36 | return combine(rmq(x, y, l, m, left(id)), rmq(x, y, m, r, right(id))); 37 | } 38 | 39 | void add_lazy(long id, long val) { 40 | tree[id] += val; 41 | lazy[id] += val; 42 | } 43 | 44 | void propagate(long id) { 45 | long id_l = left(id); 46 | long id_r = right(id); 47 | if (tree.count(id) && !tree.count(id_l)) { 48 | // create child nodes and copy info forward 49 | tree[id_l] = tree[id]; 50 | tree[id_r] = tree[id]; 51 | } 52 | else if (lazy[id]) { 53 | add_lazy(id_l, lazy[id]); 54 | add_lazy(id_r, lazy[id]); 55 | } 56 | lazy[id] = 0; 57 | } 58 | 59 | void add(long x, long y, long val, long l, long r, long id = 1) { 60 | if (x >= r || y <= l) return; // fully out of range 61 | if (x <= l && r <= y) { // fully in range 62 | 63 | add_lazy(id, val); 64 | return; 65 | } 66 | 67 | propagate(id); 68 | long m = (l + r) / 2; 69 | add(x, y, val, l, m, left(id)); 70 | add(x, y, val, m, r, right(id)); 71 | tree[id] = combine(tree[left(id)], tree[right(id)]); 72 | } 73 | 74 | long left(long id) { 75 | return 2 * id; 76 | } 77 | 78 | long right(long id) { 79 | return 2 * id + 1; 80 | } 81 | 82 | long combine(long a, long b) { 83 | return max(a, b); 84 | } 85 | }; 86 | -------------------------------------------------------------------------------- /bitset.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class BitSet; 5 | 6 | class BitSetReference { 7 | friend class BitSet; 8 | BitSetReference() ; // no public constructor 9 | unsigned int *word; 10 | int ind; 11 | public: 12 | operator bool() const ; // convert to bool 13 | BitSetReference(BitSet* bitset, int n); 14 | BitSetReference& operator= (bool x) ; // assign bool 15 | BitSetReference& operator= (const BitSetReference& x) ; // assign bit 16 | }; 17 | 18 | class BitSet { 19 | friend class BitSetReference; 20 | vector a; 21 | size_t w; 22 | int n; 23 | size_t _size; 24 | public: 25 | BitSet(): n(0), w(sizeof(unsigned int)), _size(0) {} 26 | 27 | BitSet(int n, bool v = 0): n(n), w(sizeof(int)) { 28 | _size = n/w; 29 | if(n%w) _size++; 30 | a.resize(_size, v ? ~1 : 0); 31 | } 32 | 33 | void push(bool b) { 34 | n++; 35 | _size = n/w; 36 | if(n%w) _size++; 37 | if(_size!=a.size()) 38 | a.resize(_size); 39 | (*this)[n-1] = b; 40 | } 41 | 42 | void pop() { 43 | if(!n)return; 44 | n--; 45 | _size = n/w; 46 | if(n%w) _size++; 47 | if(_size!=a.size()) 48 | a.resize(_size); 49 | } 50 | 51 | BitSetReference back() { 52 | return (*this)[n-1]; 53 | } 54 | 55 | size_t size() { 56 | return _size; 57 | } 58 | 59 | BitSetReference operator[] (int n) { 60 | return BitSetReference(this, n); 61 | } 62 | 63 | }; 64 | 65 | BitSetReference::BitSetReference(BitSet* bitset, int n) { 66 | word = &(bitset->a[(n/bitset->w)]); 67 | ind = n%(bitset->w); 68 | } 69 | 70 | BitSetReference& BitSetReference::operator= (bool x) { 71 | 72 | if(x) 73 | *word |= (1<= MOD) 5 | return res - MOD; 6 | return res; 7 | } 8 | 9 | int mult(int a, int b) 10 | { 11 | long long res = a; 12 | res *= b; 13 | if(res >= MOD) 14 | return res % MOD; 15 | return res; 16 | } 17 | 18 | 19 | struct matrix 20 | { 21 | int SZ; 22 | vector> arr; 23 | matrix(int s){ 24 | SZ = s; 25 | arr.resize(s, vector(s)); 26 | } 27 | void reset() 28 | { 29 | for(int i = 0; i < SZ; i++){ 30 | for(int j = 0; j < SZ; j++){ 31 | arr[i][j] = 0; 32 | } 33 | } 34 | } 35 | 36 | void makeiden() 37 | { 38 | reset(); 39 | for(int i=0;i>= 1; 96 | } 97 | return res; 98 | } 99 | 100 | vector multiply_vector(matrix &a, vector &b){ 101 | int SZ = a.SZ; 102 | vector ans(a.SZ); 103 | for(int i = 0; i < SZ; i++){ 104 | int curr = 0; 105 | for(int j = 0; j < SZ; j++){ 106 | curr = (curr + (b[j] * a.arr[i][j]) % MOD) % MOD; 107 | } 108 | ans[i] = curr; 109 | } 110 | return ans; 111 | } 112 | 113 | vector multiply_vector(vector &b, matrix &a){ 114 | int SZ = a.SZ; 115 | vector ans(a.SZ); 116 | for(int i = 0; i < SZ; i++){ 117 | int curr = 0; 118 | for(int j = 0; j < SZ; j++){ 119 | curr = add(curr, mul(a.arr[j][i], b[j])); 120 | } 121 | ans[i] = curr; 122 | } 123 | return ans; 124 | } 125 | -------------------------------------------------------------------------------- /segment_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int N = 1 << 17; 6 | 7 | struct node{ 8 | int cnt; 9 | void assign(int value){ 10 | cnt = value; 11 | } 12 | void update(int value){ 13 | cnt += value; 14 | } 15 | void combine(node &left, node &right){ 16 | cnt = left.cnt + right.cnt; 17 | } 18 | }; 19 | 20 | int n, a[N], lazy[N]; 21 | node tree[2*N]; 22 | 23 | // [l, r) 24 | void build(int id = 1, int l = 0, int r = n){ 25 | if(l+1 == r){ 26 | tree[id].assign(a[l]); 27 | return; 28 | } 29 | int left = id<<1, right = left+1, mid = (l+r)>>1; 30 | 31 | build(left, l, mid); build(right, mid, r); 32 | 33 | tree[id].combine(tree[left], tree[right]); 34 | return; 35 | } 36 | 37 | // point update -> update(index, value); 38 | void update(int index, int val, int id = 1, int l = 0, int r = n){ 39 | if(l+1 == r){ 40 | tree[id].assign(val); 41 | return; 42 | } 43 | int left = id<<1, right = left+1, mid = (l+r)>>1; 44 | 45 | if(index < mid) update(index, val, left, l, mid); 46 | else update(index, val, right, mid, r); 47 | 48 | tree[id].combine(tree[left], tree[right]); 49 | } 50 | 51 | 52 | // range update and utility functions 53 | void upd(int id,int l,int r,int x){ // update the current node and its index in the lazy array 54 | lazy[id] += x; 55 | tree[id].update((r - l) * x); 56 | } 57 | 58 | void shift(int id,int l,int r){ //propogate update information to the children 59 | if(lazy[id] and l+1 < r){ 60 | int mid = (l+r)/2; 61 | upd(id * 2, l, mid, lazy[id]); 62 | upd(id * 2 + 1, mid, r, lazy[id]); 63 | lazy[id] = 0; // passing is done, reset the index in the lazy array 64 | } 65 | } 66 | 67 | // range update -> update(x, y, val); 68 | void update(int x, int y, int val, int id = 1, int l = 0, int r = n){ 69 | if(x >= r or l >= y) return; 70 | if(x <= l && r <= y){ 71 | upd(id, l, r, val); 72 | return; 73 | } 74 | 75 | shift(id, l, r); // pass the updates to the children 76 | 77 | int left = id<<1, right = left+1, mid = (l+r)>>1; 78 | 79 | update(x, y, val, left, l, mid); 80 | update(x, y, val, right, mid, r); 81 | 82 | tree[id].combine(tree[left], tree[right]); 83 | return; 84 | } 85 | 86 | // range query -> query(x, y); 87 | // for point query, traverse like in point update 88 | int query(int x, int y, int id = 1, int l = 0, int r = n){ 89 | if(x >= r or l >= y) return 0; 90 | if(x <= l && r <= y) return tree[id].cnt; 91 | 92 | shift(id, l, r); //use this with lazy propogation 93 | 94 | int left = id<<1, right = left+1, mid = (l+r)>>1; 95 | 96 | return query(x, y, left, l, mid) + query(x, y, right, mid, r); 97 | } 98 | 99 | int main(){ 100 | return 0; 101 | } -------------------------------------------------------------------------------- /segment_tree_class.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/falling-squares 2 | 3 | struct segment_tree { 4 | vector tree; 5 | vector lazy; 6 | int n; 7 | 8 | segment_tree(int n) { 9 | int size = 1; 10 | while(size < n) { 11 | size *= 2; 12 | } 13 | n = size; 14 | tree.resize(2 * size); 15 | lazy.assign(size, -1); 16 | this->n = n; 17 | } 18 | 19 | // [x, y) 20 | int query(int x, int y) { 21 | return query(x, y, 1, 0, n); 22 | } 23 | 24 | // point update 25 | void update(int x, int val) { 26 | update(x, val, 1, 0, n); 27 | } 28 | 29 | // range update [x, y) 30 | void update(int x, int y, int val) { 31 | update(x, y, val, 1, 0, n); 32 | } 33 | 34 | private: 35 | // point update 36 | void update(int x, int val, int id, int l, int r) { 37 | if (l + 1 == r) { 38 | tree[id] = val; 39 | return; 40 | } 41 | int mid = (l + r) / 2; 42 | if (x < mid) update(x, val, left(id), l, mid); 43 | else update(x, val, right(id), mid, r); 44 | 45 | tree[id] = combine(tree[left(id)], tree[right(id)]); 46 | } 47 | 48 | void update_lazy(int id, int val) { 49 | tree[id] = val; 50 | if (id < n) 51 | lazy[id] = val; 52 | } 53 | 54 | void update(int x, int y, int val, int id, int l, int r) { 55 | // fully exclusive 56 | if (y <= l || r <= x) return; 57 | 58 | // fully inclusive 59 | if (x <= l && r <= y) { 60 | update_lazy(id, val); 61 | return; 62 | } 63 | 64 | propagate(id); 65 | 66 | int m = (l + r) / 2; 67 | update(x, y, val, left(id), l, m); 68 | update(x, y, val, right(id), m, r); 69 | 70 | tree[id] = combine(tree[left(id)], tree[right(id)]); 71 | } 72 | 73 | void propagate(int id) { 74 | if (id < n && ~lazy[id]) { 75 | update_lazy(left(id), lazy[id]); 76 | update_lazy(right(id), lazy[id]); 77 | lazy[id] = -1; 78 | } 79 | } 80 | 81 | int left(int id) { 82 | return id * 2; 83 | } 84 | int right(int id) { 85 | return id * 2 + 1; 86 | } 87 | 88 | int query( int x, int y, int id, int l, int r) { 89 | if (x <= l && r <= y) return tree[id]; 90 | if (y <= l || r <= x) return 0; 91 | 92 | propagate(id); 93 | 94 | int mid = (l + r) / 2; 95 | 96 | return combine(query(x, y, left(id), l, mid), query(x, y, right(id), mid, r)); 97 | } 98 | 99 | int combine(int a, int b) { 100 | return max(a, b); 101 | } 102 | }; 103 | -------------------------------------------------------------------------------- /template.cpp: -------------------------------------------------------------------------------- 1 | // g++ -std=c++14 2 | 3 | 4 | #include 5 | 6 | typedef long long ll; 7 | typedef long double lld; 8 | using namespace std; 9 | 10 | const bool DEBUG = 1; 11 | 12 | #define sd(x) scanf("%d",&x) 13 | #define sd2(x,y) scanf("%d%d",&x,&y) 14 | #define sd3(x,y,z) scanf("%d%d%d",&x,&y,&z) 15 | #define endl "\n" 16 | #define fi first 17 | #define se second 18 | #define pb(x) push_back(x) 19 | #define mp(x,y) make_pair(x,y) 20 | #define LET(x, a) __typeof(a) x(a) 21 | #define foreach(it, v) for(LET(it, v.begin()); it != v.end(); it++) 22 | #define MEMS(a,b) memset(a,b,sizeof(a)) 23 | #define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); 24 | #define __ freopen("input.txt","r",stdin);freopen("output.txt","w",stdout); 25 | #define all(c) c.begin(),c.end() 26 | #define inp(v) {for(auto it = v.begin(); it!=v.end(); it++)cin >> *it;} 27 | #define inf 1000000000000000001 28 | #define epsilon 1e-6 29 | #define int ll 30 | #define RUN_T int _t; cin>>_t; while(_t--) 31 | 32 | #define tr(...) if(DEBUG) {cout<<__FUNCTION__<<' '<<__LINE__<<" = ";trace(#__VA_ARGS__, __VA_ARGS__);} 33 | 34 | template 35 | ostream& operator<<(ostream& out,pair const& p){out<<'('< 38 | ostream& operator<<(ostream& out,set const& v){ 39 | for(auto i = v.begin(); i!=v.end(); i++)out<<(*i)<<' ';return out;} 40 | 41 | template 42 | ostream& operator<<(ostream& out,map const& v){ 43 | for(auto i = v.begin(); i!=v.end(); i++)out<<"\n"<<(i->first)<<" : "<<(i->second);return out;} 44 | 45 | template 46 | ostream& operator<<(ostream& out,unordered_map const& v){ 47 | for(auto i = v.begin(); i!=v.end(); i++)out<<"\n"<<(i->first)<<" : "<<(i->second);return out;} 48 | 49 | template 50 | ostream& operator<<(ostream& out,multiset const& v){ 51 | for(auto i = v.begin(); i!=v.end(); i++)out<<(*i)<<' ';return out;} 52 | 53 | template 54 | ostream& operator<<(ostream& out,unordered_set const& v){ 55 | for(auto i = v.begin(); i!=v.end(); i++)out<<(*i)<<' ';return out;} 56 | 57 | template 58 | ostream& operator<<(ostream& out,unordered_multiset const& v){ 59 | for(auto i = v.begin(); i!=v.end(); i++)out<<(*i)<<' ';return out;} 60 | 61 | template 62 | ostream& operator<<(ostream& out,vector const& v){ 63 | ll l=v.size();for(ll i=0;i0)out< 66 | void trace(const char* name, T&& arg1){cout< 69 | void trace(const char* names, T&& arg1, Args&&... args){ 70 | const char* comma = strchr(names + 1, ',');cout.write(names, comma-names)<<" : "< count number of bits 77 | 78 | int32_t main(){ _ 79 | 80 | } 81 | 82 | -------------------------------------------------------------------------------- /combination.cpp: -------------------------------------------------------------------------------- 1 | // g++ -std=c++14 2 | 3 | /* 4 | 5 | Today might be the chance to grasp the chance to let your talent bloom. 6 | May be tomorrow, the day after, or next year... 7 | May be even when you are 30. I'm not sure if physique has anything to do with it 8 | but if you think that it will never come, it probably never will. 9 | 10 | - Tooru Oikawa. 11 | 12 | */ 13 | 14 | 15 | #include 16 | 17 | typedef long long ll; 18 | typedef long double lld; 19 | using namespace std; 20 | 21 | #define sd(x) scanf("%d",&x) 22 | #define sd2(x,y) scanf("%d%d",&x,&y) 23 | #define sd3(x,y,z) scanf("%d%d%d",&x,&y,&z) 24 | #define endl "\n" 25 | #define fi first 26 | #define se second 27 | #define pb(x) push_back(x) 28 | #define mp(x,y) make_pair(x,y) 29 | #define LET(x, a) __typeof(a) x(a) 30 | #define foreach(it, v) for(LET(it, v.begin()); it != v.end(); it++) 31 | #define MEMS(a,b) memset(a,b,sizeof(a)) 32 | #define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); 33 | #define __ freopen("input.txt","r",stdin);freopen("output.txt","w",stdout); 34 | #define all(c) c.begin(),c.end() 35 | #define inf 1000000000000000001 36 | 37 | #define tr(...) cout<<__FUNCTION__<<' '<<__LINE__<<" = ";trace(#__VA_ARGS__, __VA_ARGS__) 38 | 39 | template 40 | ostream& operator<<(ostream& out,pair const& p){out<<'('< 43 | ostream& operator<<(ostream& out,vector const& v){ 44 | ll l=v.size();for(ll i=0;i0)out< 47 | void trace(const char* name, T&& arg1){cout< 50 | void trace(const char* names, T&& arg1, Args&&... args){ 51 | const char* comma = strchr(names + 1, ',');cout.write(names, comma-names)<<" : "< 0) { 76 | if(t & 1) ans = 1LL * ans * x % MOD; 77 | x = 1LL * x * x % MOD; 78 | t >>= 1; 79 | } 80 | return ans; 81 | } 82 | 83 | void init_fac(){ 84 | fac[0] = 1; 85 | for(int i = 1; i < N; i++){ 86 | fac[i] = (fac[i - 1] * i) % MOD; 87 | } 88 | ifac[N - 1] = power(fac[N - 1], MOD - 2); 89 | for(int i = N - 1; i >= 1; i--){ 90 | ifac[i - 1] = (ifac[i] * i) % MOD; 91 | } 92 | } 93 | 94 | int C(int n, int m) 95 | { 96 | if(n < m) return 0; 97 | return fac[n] * (1LL * ifac[m] * ifac[n - m] % MOD) % MOD; 98 | } 99 | 100 | int s(int n, int k){ 101 | if(n == 0) return (k == 0); 102 | if(k == 0) return (n == 0); 103 | int ans = 0; 104 | int sg[2] = {1, MOD - 1}; 105 | for(int i = 0; i <= k; i++){ 106 | ans = (ans + (sg[i & 1LL] * ((C(k, i) * power(k - i, n)) % MOD)) % MOD) % MOD; 107 | } 108 | ans = (ans * ifac[k]) % MOD; 109 | return ans; 110 | } 111 | 112 | 113 | int32_t main(){ _ 114 | init_fac(); 115 | } 116 | -------------------------------------------------------------------------------- /sparse_segment_tree.cpp: -------------------------------------------------------------------------------- 1 | //Tanuj Khattar 2 | #include 3 |   4 | using namespace std; 5 |   6 | typedef pair II; 7 | typedef vector< II > VII; 8 | typedef vector VI; 9 | typedef vector< VI > VVI; 10 | typedef long long int LL; 11 | typedef unsigned long long int ULL; 12 |   13 | #define PB push_back 14 | #define MP make_pair 15 | #define F first 16 | #define S second 17 | #define SZ(a) (int)(a.size()) 18 | #define ALL(a) a.begin(),a.end() 19 | #define SET(a,b) memset(a,b,sizeof(a)) 20 | #define LET(x,a) __typeof(a) x(a) 21 |   22 | #define rep(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end))) 23 | //Works for forward as well as backward iteration 24 |   25 | #define gu getchar 26 | #define pu putchar 27 | #define si(n) scanf("%d",&n) 28 | #define dout(n) printf("%d\n",n) 29 | #define sll(n) scanf("%lld",&n) 30 | #define lldout(n) printf("%lld\n",n) 31 |   32 | #define DRT() int t; si(t); while(t--) 33 |   34 | #define PlUSWRAP(index,n) index = (index+1)%n //index++; if(index>=n) index=0 35 | #define MINUSWRAP(index,n) index = (index + n -1)%n //index--; if(index<0) index=n-1 36 | #define ROUNDOFFINT(d) d = (int)((double)d + 0.5) //Round off d to nearest integer 37 |   38 | #define FLUSHN while(gu()!='\n') 39 | #define FLUSHS while(gu()!=' ') 40 |   41 | #define TRACE 42 |   43 | #ifdef TRACE 44 | #define trace1(x) cerr << #x << ": " << x << endl; 45 | #define trace2(x, y) cerr << #x << ": " << x << " | " << #y << ": " << y << endl; 46 | #define trace3(x, y, z) cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl; 47 | #define trace4(a, b, c, d) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl; 48 | #define trace5(a, b, c, d, e) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl; 49 | #define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl; 50 |   51 | #else 52 |   53 | #define trace1(x) 54 | #define trace2(x, y) 55 | #define trace3(x, y, z) 56 | #define trace4(a, b, c, d) 57 | #define trace5(a, b, c, d, e) 58 | #define trace6(a, b, c, d, e, f) 59 |   60 | #endif 61 |   62 | //FILE *fin = freopen("in","r",stdin); 63 | //FILE *fout = freopen("out","w",stdout); 64 |   65 | class sparse_segtree{ 66 | LL low,high; //range of the segtree [low,high) 67 | struct node{ 68 | LL mx; 69 | int index; 70 | node *l,*r; 71 | node(){l=r=NULL;mx=0;} 72 | }; 73 | typedef node* pnode; 74 | pnode head; 75 | pair value(pnode t) 76 | { 77 | return t?MP(t->mx,t->index):MP(0ll,0); 78 | } 79 | void point_update(pnode& t,LL l,LL r,LL pos,LL val,int idx) 80 | { 81 | if(pos=r)return; 82 | if(!t) t = new node; 83 | if(l==r-1 && l==pos) 84 | { 85 | t->mx = val; 86 | t->index = idx; 87 | return; 88 | } 89 | LL mid = (l+r)>>1; 90 | point_update(t->l,l,mid,pos,val,idx); 91 | point_update(t->r,mid,r,pos,val,idx); 92 | pair mx = max(value(t->l),value(t->r)); 93 | t->mx = mx.F; 94 | t->index = mx.S; 95 | } 96 | pair range_query(pnode t,LL l,LL r,LL L,LL R) 97 | { 98 | if(l>=R || L>=r)return MP(0ll,0); 99 | if(!t)return MP(0ll,0); 100 | if(l>=L && r<=R) 101 | return MP(t->mx,t->index); 102 | LL mid = (l+r)>>1; 103 | pair la = range_query(t->l,l,mid,L,R); 104 | pair ra = range_query(t->r,mid,r,L,R); 105 | return max(la,ra); 106 | } 107 | public: 108 | sparse_segtree(){low=0,high=0,head=NULL;} 109 | sparse_segtree(LL l,LL h) 110 | { 111 | low = l; 112 | high = h; 113 | head = NULL; 114 | } 115 | void update(LL pos,LL val,int idx) 116 | { 117 | point_update(head,low,high,pos,val,idx); 118 | } 119 | pair query(LL L,LL R) 120 | { 121 | if(L>=R)return MP(0ll,0); 122 | return range_query(head,low,high,L,R); 123 | } 124 | }; 125 | const LL MXH = LL(1e15)+10; 126 | const int N = int(1e5)+10; 127 | int dp[N]; 128 | int ans[N]; 129 | LL A[N]; 130 | int main() 131 | { 132 | sparse_segtree H(1,MXH); 133 | int n,d; 134 | si(n);si(d); 135 | for(int i=1;i<=n;i++) 136 | sll(A[i]); 137 | for(int i=1;i<=n;i++) 138 | { 139 | pair la = H.query(1,A[i]-d+1); 140 | pair ra = H.query(A[i]+d,MXH); 141 | pair mx = max(la,ra); 142 | dp[i] = mx.F + 1; 143 | ans[i] = mx.S; 144 | H.update(A[i],dp[i],i); 145 | } 146 | int mx = 0; 147 | for(int i=1;i<=n;i++) 148 | if(dp[i]>dp[mx]) 149 | mx = i; 150 | dout(dp[mx]); 151 | stack s; 152 | while(mx>0) 153 | { 154 | s.push(mx); 155 | mx = ans[mx]; 156 | } 157 | while(!s.empty()) 158 | { 159 | printf("%d ",s.top()); 160 | s.pop(); 161 | } 162 | printf("\n"); 163 | return 0; 164 | } --------------------------------------------------------------------------------