├── testing ├── in ├── s.sh ├── gen_tree.cpp ├── a.cpp ├── brute.cpp ├── gen.cpp ├── info.txt └── gen_tree2.cpp ├── lectures ├── fake-lecture │ └── fake.cpp └── binary-search │ ├── sqrt.py │ ├── find-minimum-in-rotated-sorted-array.cpp │ ├── find-minimum-in-rotated-sorted-array.py │ ├── first-bad-version.py │ ├── first-bad-version.cpp │ ├── guess-number.py │ ├── guess-number.cpp │ ├── old-implementation.cpp │ ├── sqrt.cpp │ ├── search-in-rotated-sorted-array.py │ └── search-in-rotated-sorted-array.cpp ├── POI ├── difference │ └── in ├── tree-rotations │ ├── in │ └── kd_ac.cpp ├── temperature │ ├── in │ ├── kd_ac.cpp │ └── author.cpp ├── garbage │ └── in └── 22-movie-goer.cpp ├── AOC-2020 ├── 13-search │ ├── in │ ├── in2 │ ├── shuttle.cpp │ └── shuttle2.cpp └── 20-jigsaw │ ├── corners.cpp │ └── in ├── README.md ├── files └── parade_en.pdf ├── AOC-2024 ├── template.cpp ├── 01.cpp ├── 22.cpp ├── 01-part2.cpp ├── 14.cpp ├── 04-part2.cpp ├── 13.cpp ├── 02.cpp ├── 23.cpp ├── 09-easy.cpp ├── 18.cpp ├── 06.cpp ├── 07.cpp ├── 03.cpp ├── 04.cpp ├── 19.cpp ├── 19-part2.cpp ├── 24.cpp ├── 10.cpp ├── 03-part2.cpp ├── 11.cpp ├── 22-part2.cpp ├── 23-part2.cpp ├── 09.cpp ├── 05.cpp ├── 25.cpp ├── 14-part2.cpp ├── 12.cpp ├── 09-part2.cpp ├── 18-part2.cpp ├── 02-part2.cpp ├── 13-part2.cpp ├── 06-part2.cpp ├── 08.cpp ├── 20.cpp ├── 15.cpp ├── 16.cpp └── 05-part2.cpp ├── hashcode_2020_final_round.pdf ├── PSUT-coding-marathon ├── s.sh ├── templates.cpp ├── a.cpp ├── gen.cpp ├── b.cpp ├── d.cpp └── e.cpp ├── GCJ ├── 2020 │ └── qual │ │ ├── E-slides-construction.pdf │ │ ├── B-nesting-depth.cpp │ │ ├── C-parenting-prtntntn.cpp │ │ └── A-vestigium.cpp └── 2021 │ └── 1C │ ├── closest_pick.cpp │ └── roaring_years.cpp ├── hashcode └── 2021_practice │ └── 2021_practice.pdf ├── CSES └── Introductory │ ├── 09-bit-strings.cpp │ ├── 10-trailing.cpp │ ├── 04-increasing.cpp │ ├── 03-repetitions.cpp │ ├── 02-missing.cpp │ ├── 11-coin-piles.cpp │ ├── 14-tower-of-hanoi.cpp │ ├── 01-weird.cpp │ ├── 06-number.cpp │ ├── 05-permutations.cpp │ ├── 13-gray.cpp │ ├── 07-two-knights.cpp │ ├── 16-apple.cpp │ ├── 19-mex-grid.cpp │ ├── 17-chessboard.cpp │ ├── 20-knight-moves.cpp │ ├── 22-digit-queries.cpp │ ├── 15-creating-strings.cpp │ ├── 08-two-sets.cpp │ ├── 21-grid-coloring.cpp │ ├── 12-palindrome.cpp │ └── 18-raab.cpp ├── leetcode ├── april-2020-challenge │ ├── 01-single-number.cpp │ ├── 03-maximum-subarray.cpp │ ├── 23-bitwise-and-of-range.cpp │ ├── 04-move-zeroes.cpp │ ├── 05-best-buy-sell-stock.cpp │ ├── 06-group-anagrams.cpp │ ├── 29-binary-tree-max-path-sum.cpp │ ├── 14-perform-string-shifts.cpp │ ├── 08-middle-of-linked-list.cpp │ ├── 12-last-stone-weight.py │ ├── 22-subarray-sum-equals-k.cpp │ ├── 18-minimum-path-sum.cpp │ ├── 16-valid-varenthesis-string.cpp │ ├── 11-diameter-of-binary-tree.cpp │ ├── 02-happy-number.cpp │ ├── 27-maximal-square.cpp │ ├── 09-backspace-string-compare.cpp │ ├── 10-min-stack.cpp │ ├── 19-search-in-rotated-sorted-array.cpp │ ├── 13-contiguous-array.py │ ├── 07-counting-elements.cpp │ ├── 25-jump-game.cpp │ ├── 26-LCS-longest-common-subsequence.cpp │ ├── 17-number-of-islands.cpp │ ├── 20-construct-BST-from-traversal.cpp │ ├── 15-product-of-array-except.cpp │ └── 21-leftmost-column-with-1.cpp ├── 1328-break-a-palindrome.cpp ├── 21-merge-two-sorted-lists.cpp ├── 34-find-first-and-last-position-in-sorted.cpp ├── 1223-dice.cpp ├── 1483-kth-ancestor.cpp ├── 1222-queens.cpp ├── 1345-jump-game-iv.cpp ├── 1048-longest-string-chain.cpp ├── 1224-frequency.cpp └── 301-remove-invalid-parentheses.cpp ├── matrix-exponentiation ├── links.txt ├── c2.cpp ├── a.cpp ├── c.cpp ├── b.cpp ├── b2.cpp ├── d2.cpp ├── f2.cpp ├── d.cpp ├── i.cpp ├── f.cpp ├── e2.cpp └── h.cpp ├── templates ├── gp_hash_table.cpp └── ordered_set.cpp ├── pairs ├── ac.py └── ac.cpp ├── two-arrays-and-sum-of-functions └── ac.cpp ├── partition-into-permutations └── ac.cpp ├── rmq_sparse_table.cpp ├── LICENSE ├── isolation └── brute.cpp ├── codeforces └── 614a-maze-game.cpp ├── painting-the-fence ├── solution2.cpp └── solution1.cpp ├── atcoder-dp ├── a.cpp ├── b.cpp ├── k.cpp ├── l.cpp ├── i.cpp ├── c.cpp ├── d.cpp ├── x.cpp ├── h.cpp ├── o.cpp ├── g.cpp ├── n.cpp ├── e.cpp ├── p.cpp └── m.cpp ├── and-reachability └── ac.cpp └── lca.cpp /testing/in: -------------------------------------------------------------------------------- 1 | 4 2 | 10 30 20 40 3 | -------------------------------------------------------------------------------- /lectures/fake-lecture/fake.cpp: -------------------------------------------------------------------------------- 1 | hi 2 | -------------------------------------------------------------------------------- /POI/difference/in: -------------------------------------------------------------------------------- 1 | 10 2 | aabbaaabab 3 | -------------------------------------------------------------------------------- /AOC-2020/13-search/in: -------------------------------------------------------------------------------- 1 | 939 2 | 7,13,x,x,59,x,31,19 3 | -------------------------------------------------------------------------------- /POI/tree-rotations/in: -------------------------------------------------------------------------------- 1 | 3 2 | 0 3 | 0 4 | 3 5 | 1 6 | 2 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # youtube 2 | codes for my streams and YT videos 3 | -------------------------------------------------------------------------------- /POI/temperature/in: -------------------------------------------------------------------------------- 1 | 6 2 | 6 10 3 | 1 5 4 | 4 8 5 | 2 5 6 | 6 8 7 | 3 5 8 | -------------------------------------------------------------------------------- /files/parade_en.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Errichto/youtube/HEAD/files/parade_en.pdf -------------------------------------------------------------------------------- /AOC-2024/template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /hashcode_2020_final_round.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Errichto/youtube/HEAD/hashcode_2020_final_round.pdf -------------------------------------------------------------------------------- /PSUT-coding-marathon/s.sh: -------------------------------------------------------------------------------- 1 | for((i=1;;i++)); do 2 | echo $i 3 | ./gen $i > int 4 | ./f < int || break 5 | done 6 | -------------------------------------------------------------------------------- /POI/garbage/in: -------------------------------------------------------------------------------- 1 | 6 8 2 | 1 2 0 1 3 | 2 3 1 0 4 | 1 3 0 1 5 | 2 4 0 0 6 | 3 5 1 1 7 | 4 5 0 1 8 | 5 6 0 1 9 | 4 6 0 1 10 | -------------------------------------------------------------------------------- /GCJ/2020/qual/E-slides-construction.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Errichto/youtube/HEAD/GCJ/2020/qual/E-slides-construction.pdf -------------------------------------------------------------------------------- /hashcode/2021_practice/2021_practice.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Errichto/youtube/HEAD/hashcode/2021_practice/2021_practice.pdf -------------------------------------------------------------------------------- /testing/s.sh: -------------------------------------------------------------------------------- 1 | for((i = 1; ; ++i)); do 2 | echo $i 3 | ./gen $i > int 4 | # ./a < int > out1 5 | # ./brute < int > out2 6 | # diff -w out1 out2 || break 7 | diff -w <(./a < int) <(./brute < int) || break 8 | done 9 | -------------------------------------------------------------------------------- /AOC-2020/13-search/in2: -------------------------------------------------------------------------------- 1 | 1000508 2 | 29,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,467,x,x,x,x,x,x,x,23,x,x,x,x,13,x,x,x,17,x,19,x,x,x,x,x,x,x,x,x,x,x,443,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,41 3 | -------------------------------------------------------------------------------- /AOC-2020/20-jigsaw/corners.cpp: -------------------------------------------------------------------------------- 1 | // ... 2 | long long product = 1; 3 | for(Tile a : tiles) { 4 | for(Tile b : tiles) { 5 | if(a.matches(b) && a.id != b.id) { 6 | degree++; 7 | } 8 | } 9 | if(degree == 2) { // corner 10 | product *= a.id; 11 | } 12 | } 13 | cout << product; 14 | } 15 | -------------------------------------------------------------------------------- /CSES/Introductory/09-bit-strings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int MOD = 1'000'000'007; 5 | 6 | int main() { 7 | int n; 8 | cin >> n; 9 | int answer = 1; 10 | for (int i = 0; i < n; i++) { // O(N) 11 | answer = (2 * answer) % MOD; 12 | } 13 | cout << answer << "\n"; 14 | } 15 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/01-single-number.cpp: -------------------------------------------------------------------------------- 1 | // day 1 of Leetcode April 2020 Challenge, by Errichto 2 | // problem Single Number 3 | class Solution { 4 | public: 5 | int singleNumber(vector& nums) { 6 | int x = 0;; 7 | for(int a : nums) { 8 | x ^= a; 9 | } 10 | return x; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /CSES/Introductory/10-trailing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n; 6 | cin >> n; 7 | int answer = 0; 8 | for (long long m = 5; m <= n; m *= 5) { 9 | answer += n / m; 10 | } 11 | cout << answer << "\n"; 12 | // cout << n / 5 + n / 25 + n / 125 + n / 625 + ... << "\n"; 13 | } 14 | // 5! = 5 * 4 * 3 * 2 * 1 = 120 15 | -------------------------------------------------------------------------------- /matrix-exponentiation/links.txt: -------------------------------------------------------------------------------- 1 | Matrix Exponentiation 2 | video tutorial - https://www.youtube.com/watch?v=eMXNWcbw75E 3 | Codeforces article with discussion, hints and text tutorial - https://codeforces.com/blog/entry/80195 4 | editorial for easy problems ABCDEF - https://www.youtube.com/watch?v=kQuCOFzWoa0 5 | editorial for hard problems GHI - https://www.youtube.com/watch?v=RA_SpxP2t54 6 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/03-maximum-subarray.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxSubArray(vector& nums) { 4 | int ans = INT_MIN; 5 | int a = 0; 6 | for(int x : nums) { 7 | // could be just : ans = max(ans, a + x); a = max(0, a + x); 8 | a += x; 9 | ans = max(ans, a); 10 | a = max(a, 0); 11 | } 12 | return ans; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /testing/gen_tree.cpp: -------------------------------------------------------------------------------- 1 | // generating a tree in a simple way 2 | #include 3 | using namespace std; 4 | 5 | int rand(int a, int b) { 6 | return a + rand() % (b - a + 1); 7 | } 8 | 9 | int main(int argc, char* argv[]) { 10 | srand(atoi(argv[1])); 11 | int n = rand(2, 20); 12 | printf("%d\n", n); 13 | for(int i = 2; i <= n; ++i) { 14 | printf("%d %d\n", rand(1, i - 1), i); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /CSES/Introductory/04-increasing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // greedy O(N) 5 | 6 | int main() { 7 | int n; 8 | cin >> n; 9 | vector a(n); 10 | for (int i = 0; i < n; i++) { 11 | cin >> a[i]; 12 | } 13 | long long answer = 0; 14 | for (int i = 1; i < n; i++) { 15 | if (a[i] < a[i-1]) { 16 | answer += a[i-1] - a[i]; 17 | a[i] = a[i-1]; 18 | } 19 | } 20 | cout << answer << "\n"; 21 | } 22 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/23-bitwise-and-of-range.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int rangeBitwiseAnd(int m, int n) { 4 | int answer = 0; 5 | for(int bit = 30; bit >= 0; bit--) { 6 | if((m & (1 << bit)) != (n & (1 << bit))) { 7 | break; 8 | } 9 | else { 10 | answer |= (m & (1 << bit)); 11 | } 12 | } 13 | return answer; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /AOC-2024/01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1000; 5 | 6 | int main() { 7 | vector a, b; 8 | for (int i = 0; i < N; i++) { 9 | int x, y; 10 | cin >> x >> y; 11 | a.push_back(x); 12 | b.push_back(y); 13 | } 14 | sort(a.begin(), a.end()); 15 | sort(b.begin(), b.end()); 16 | long long sum = 0; 17 | for (int i = 0; i < N; i++) { 18 | sum += abs(a[i] - b[i]); 19 | } 20 | cout << sum << "\n"; 21 | } 22 | -------------------------------------------------------------------------------- /AOC-2024/22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int MOD = 1 << 24; 5 | void f(long long& x) { 6 | x ^= x * 64; 7 | x %= MOD; 8 | x ^= x / 32; 9 | x %= MOD; 10 | x ^= x * 2048LL; 11 | x %= MOD; 12 | } 13 | 14 | int main() { 15 | long long x; 16 | long long sum = 0; 17 | while (scanf("%lld", &x) != EOF) { 18 | for (int i = 0; i < 2000; i++) { 19 | f(x); 20 | } 21 | sum += x; 22 | } 23 | cout << sum << "\n"; 24 | } 25 | -------------------------------------------------------------------------------- /CSES/Introductory/03-repetitions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | string s; 6 | cin >> s; 7 | int n = s.length(); 8 | int block = 0; 9 | int answer = 0; 10 | for (int i = 0; i < n; i++) { // O(N) 11 | if (i != 0 && s[i] == s[i-1]) { 12 | block++; 13 | } 14 | else { 15 | answer = max(answer, block); 16 | block = 1; 17 | } 18 | } 19 | answer = max(answer, block); 20 | cout << answer << "\n"; 21 | } 22 | -------------------------------------------------------------------------------- /testing/a.cpp: -------------------------------------------------------------------------------- 1 | // incorrect solution for finding second smallest element 2 | #include 3 | using namespace std; 4 | // #warning TODO: remember about bigger N 5 | const int MAX_N = 1e6 + 5; 6 | int a[MAX_N]; 7 | set asd[MAX_N], asdfasd[3*MAX_N]; 8 | int main() { 9 | int n; 10 | scanf("%d", &n); 11 | for(int i = 1; i <= n; ++i) { 12 | scanf("%d", &a[i]); 13 | } 14 | sort(a + 1, a + n); 15 | printf("%d\n", a[2]); 16 | } 17 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/04-move-zeroes.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void moveZeroes(vector& nums) { 4 | int n = nums.size(); 5 | int nxt = 0; 6 | for(int x : nums) { 7 | if(x != 0) { 8 | nums[nxt] = x; 9 | nxt++; 10 | } 11 | } 12 | for(int i = nxt; i < n; i++) { 13 | nums[i] = 0; 14 | } 15 | //return nums; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /CSES/Introductory/02-missing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // alternative solution: (long long) n * (n + 1) / 2 - sum 5 | 6 | // O(N) time & memory 7 | int main() { 8 | int n; 9 | cin >> n; 10 | vector vis(n+1); 11 | // 1 .. n 12 | for (int i = 0; i < n - 1; i++) { 13 | int x; 14 | cin >> x; 15 | vis[x] = true; 16 | } 17 | for (int x = 1; x <= n; x++) { 18 | if (!vis[x]) { 19 | cout << x << "\n"; 20 | return 0; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/05-best-buy-sell-stock.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | const int INF = 1e9 + 5; 3 | public: 4 | int maxProfit(vector& prices) { 5 | int best_without_stock = 0, best_with_stock = -INF; 6 | for(int x : prices) { 7 | best_with_stock = max(best_with_stock, best_without_stock - x); 8 | best_without_stock = max(best_without_stock, best_with_stock + x); 9 | } 10 | return best_without_stock; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/06-group-anagrams.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector> groupAnagrams(vector& strs) { 4 | map> m; 5 | for(string s : strs) { 6 | string s2 = s; 7 | sort(s2.begin(), s2.end()); 8 | m[s2].push_back(s); 9 | } 10 | vector> v; 11 | for(auto pp : m) { 12 | v.push_back(pp.second); 13 | } 14 | return v; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /CSES/Introductory/11-coin-piles.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // O(T * A) 5 | 6 | void test_case() { 7 | int a, b; 8 | cin >> a >> b; 9 | if ((a + b) % 3 == 0 && a <= 2 * b && b <= 2 * a) { 10 | cout << "YES\n"; 11 | } 12 | else { 13 | cout << "NO\n"; 14 | } 15 | } 16 | 17 | int main() { 18 | int T; 19 | cin >> T; 20 | for (int rep = 0; rep < T; rep++) { 21 | test_case(); 22 | } 23 | } 24 | 25 | // a -= 1 26 | // b -= 2 27 | 28 | // or 29 | 30 | // a -= 2 31 | // b -= 1 32 | -------------------------------------------------------------------------------- /CSES/Introductory/14-tower-of-hanoi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // it is hard to avoid recursion here 5 | 6 | // O(2^N) 7 | void solve(int n, int from, int to) { 8 | if (n == 0) { 9 | return; 10 | } 11 | // int OTHER = from ^ to; 12 | int OTHER = 6 - from - to; 13 | solve(n-1, from, OTHER); 14 | cout << from << " " << to << "\n"; 15 | solve(n-1, OTHER, to); 16 | } 17 | 18 | int main() { 19 | int n; 20 | cin >> n; 21 | cout << (1 << n) - 1 << "\n"; 22 | solve(n, 1, 3); 23 | } 24 | -------------------------------------------------------------------------------- /AOC-2024/01-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 1000; 5 | 6 | int main() { 7 | vector a, b; 8 | for (int i = 0; i < N; i++) { 9 | int x, y; 10 | cin >> x >> y; 11 | a.push_back(x); 12 | b.push_back(y); 13 | } 14 | sort(a.begin(), a.end()); 15 | sort(b.begin(), b.end()); 16 | map freq; 17 | for (int x : b) { 18 | freq[x]++; 19 | } 20 | 21 | long long sum = 0; 22 | for (int x : a) { 23 | sum += (long long) x * freq[x]; 24 | } 25 | cout << sum << "\n"; 26 | } 27 | -------------------------------------------------------------------------------- /AOC-2024/14.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | long long ans[2][2]; 4 | int main() { 5 | const int W = 101; 6 | const int H = 103; 7 | // p=57,29 v=-7,-96 8 | int px, py, vx, vy; 9 | while (scanf(" p=%d,%d v=%d,%d", &px, &py, &vx, &vy) != EOF) { 10 | // printf("%d..%d\n", px, vy); 11 | px = ((px + vx * 100) % W + W) % W; 12 | py = ((py + vy * 100) % H + H) % H; 13 | if (px != W / 2 && py != H / 2) { 14 | ans[px>W/2][py>H/2]++; 15 | } 16 | } 17 | printf("%lld\n", ans[0][0] * ans[0][1] * ans[1][0] * ans[1][1]); 18 | } 19 | -------------------------------------------------------------------------------- /CSES/Introductory/01-weird.cpp: -------------------------------------------------------------------------------- 1 | // https://cses.fi/problemset 2 | // problems 1-12 (up to Palindrome Reorder): https://www.youtube.com/live/pL7Jy3g62GM?si=f3qegjGinj4FMVOd 3 | // problems 13-24 (from Gray Code): https://www.youtube.com/live/cRHe4Ig3JnE?si=YWQfOvMvF6D5lzc3 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | long long n; 10 | cin >> n; 11 | while (n != 1) { 12 | cout << n << " "; 13 | if (n % 2 == 0) { 14 | n /= 2; 15 | } 16 | else { 17 | n = 3 * n + 1; 18 | } 19 | } 20 | cout << "1\n"; 21 | } 22 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/29-binary-tree-max-path-sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int answer; 3 | // max path going down 4 | int dfs(TreeNode* root) { 5 | if(root == NULL) { 6 | return 0; 7 | } 8 | int x = dfs(root->left); 9 | int y = dfs(root->right); 10 | answer = max(answer, x + y + root->val); 11 | return max(0, root->val + max(x, y)); 12 | } 13 | public: 14 | int maxPathSum(TreeNode* root) { 15 | answer = INT_MIN; 16 | dfs(root); 17 | return answer; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /templates/gp_hash_table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace __gnu_pbds; 3 | struct my_hash { 4 | const uint64_t RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 5 | static uint64_t splitmix64(uint64_t x) { 6 | x += 0x9e3779b97f4a7c15; 7 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 8 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 9 | return x ^ (x >> 31); 10 | } 11 | size_t operator()(uint64_t x) const { 12 | return splitmix64(x + RANDOM); 13 | } 14 | }; 15 | // gp_hash_table m; 16 | -------------------------------------------------------------------------------- /testing/brute.cpp: -------------------------------------------------------------------------------- 1 | // slow solution for finding second smallest element 2 | #include 3 | using namespace std; 4 | int main() { 5 | int n; 6 | cin >> n; 7 | vector a(n); 8 | for(int& x : a) { 9 | cin >> x; 10 | } 11 | for(int x : a) { 12 | int count_smaller = 0; 13 | for(int y : a) { 14 | if(y < x) { 15 | ++count_smaller; 16 | } 17 | } 18 | if(count_smaller == 1) { 19 | cout << x; 20 | return 0; 21 | } 22 | } 23 | assert(false); 24 | } 25 | -------------------------------------------------------------------------------- /CSES/Introductory/06-number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void test_case() { 5 | int row, col; 6 | cin >> row >> col; 7 | int layer = max(row, col); 8 | if (layer % 2 == 1) { 9 | swap(row, col); 10 | } 11 | if (col == layer) { 12 | // vertical part 13 | cout << (long long) (layer-1)*(layer-1) + 1 + row-1 << "\n"; 14 | } 15 | else { 16 | assert(row == layer); 17 | cout << (long long) layer * layer - (col-1) << "\n"; 18 | } 19 | } 20 | 21 | int main() { 22 | int T; 23 | cin >> T; 24 | for (int rep = 0; rep < T; rep++) { 25 | test_case(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CSES/Introductory/05-permutations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // constructive problem 5 | 6 | int main() { 7 | int n; 8 | cin >> n; 9 | vector a; 10 | for (int i = 1; i <= n; i += 2) { 11 | a.push_back(i); 12 | } 13 | for (int i = 2; i <= n; i += 2) { 14 | a.push_back(i); 15 | } 16 | if (n == 4) { 17 | a = {3, 1, 4, 2}; 18 | } 19 | for (int i = 0; i < (int) a.size() - 1; i++) { 20 | if (abs(a[i] - a[i+1]) == 1) { 21 | cout << "NO SOLUTION\n"; 22 | return 0; 23 | } 24 | } 25 | for (int x : a) { 26 | cout << x << " "; 27 | } 28 | cout << "\n"; 29 | } 30 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/14-perform-string-shifts.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string stringShift(string s, vector>& shift) { 4 | int total = 0; 5 | for(vector pp : shift) { 6 | if(pp[0] == 0) { 7 | total -= pp[1]; 8 | } 9 | else { 10 | total += pp[1]; 11 | } 12 | } 13 | int n = s.length(); 14 | total %= n; 15 | if(total < 0) { 16 | total += n; 17 | } 18 | // ABCDE 19 | return s.substr(n-total) + s.substr(0, n-total); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /testing/gen.cpp: -------------------------------------------------------------------------------- 1 | // generating a random sequence of distinct elements 2 | #include 3 | using namespace std; 4 | 5 | int rand(int a, int b) { 6 | return a + rand() % (b - a + 1); 7 | } 8 | 9 | int main(int argc, char* argv[]) { 10 | srand(atoi(argv[1])); // atoi(s) converts an array of chars to int 11 | int n = rand(2, 10); 12 | printf("%d\n", n); 13 | set used; 14 | for(int i = 0; i < n; ++i) { 15 | int x; 16 | do { 17 | x = rand(1, 10); 18 | } while(used.count(x)); 19 | printf("%d ", x); 20 | used.insert(x); 21 | } 22 | puts(""); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/08-middle-of-linked-list.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode(int x) : val(x), next(NULL) {} 7 | * }; 8 | */ 9 | 10 | class Solution { 11 | public: 12 | ListNode* middleNode(ListNode* head) { 13 | ListNode* A = head; 14 | ListNode* B = head; 15 | while(B != NULL) { 16 | B = B->next; 17 | if(B == NULL) { 18 | return A; 19 | } 20 | A = A->next; 21 | B = B->next; 22 | } 23 | return A; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /leetcode/1328-break-a-palindrome.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/break-a-palindrome/ 2 | // video: https://youtu.be/iXbJ1qvKg28 3 | class Solution { 4 | public: 5 | string breakPalindrome(string s) { // O(N) 6 | int n = s.length(); 7 | if(n == 1) { 8 | return ""; 9 | } 10 | for(int i = 0; i < n; i++) { 11 | int j = n - 1 - i; 12 | if(i == j) { 13 | continue; 14 | } 15 | if(s[i] != 'a') { 16 | s[i] = 'a'; 17 | return s; 18 | } 19 | } 20 | s[n-1] = 'b'; 21 | return s; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/12-last-stone-weight.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | class Solution: 3 | def lastStoneWeight(self, stones: List[int]) -> int: 4 | size = len(stones) 5 | for i in range(size): 6 | stones[i] = -stones[i] 7 | heapq.heapify(stones) 8 | while size >= 2: 9 | y = -heapq.heappop(stones) 10 | x = -heapq.heappop(stones) 11 | if x == y: 12 | size -= 2 13 | else: 14 | size -= 1 15 | heapq.heappush(stones, -(y - x)) 16 | if size == 0: 17 | return 0 18 | return -heapq.heappop(stones) 19 | 20 | -------------------------------------------------------------------------------- /AOC-2020/13-search/shuttle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | int start; 5 | cin >> start; 6 | string s; 7 | cin >> s; 8 | vector a{0}; 9 | for(int i = 0; i < (int) s.length(); ++i) { 10 | if(s[i] == ',') { 11 | a.push_back(0); 12 | } 13 | if(isdigit(s[i])) { 14 | a.back() = 10 * a.back() + (s[i] - '0'); 15 | } 16 | } 17 | pair answer{INT_MAX, INT_MAX}; 18 | for(int x : a) { 19 | if(x != 0) { 20 | int when = (start + x - 1) / x * x; // ceil(start / x) * x 21 | answer = min(answer, make_pair(when, x * (when - start))); 22 | } 23 | } 24 | printf("%d %d\n", answer.first, answer.second); 25 | } 26 | -------------------------------------------------------------------------------- /lectures/binary-search/sqrt.py: -------------------------------------------------------------------------------- 1 | # Sqrt(x), https://leetcode.com/explore/learn/card/binary-search/125/template-i/950/ 2 | # Find the last M such that M*M <= X. 3 | class Solution: 4 | def mySqrt(self, x: int) -> int: 5 | L, R = 0, x 6 | ans = -1 # this -1 shouldn't be returned because we will find some M such that M*M <= x, e.g. M=0 is fine 7 | while L <= R: 8 | mid = L + (R - L) // 2 9 | if mid * mid <= x: 10 | ans = mid 11 | L = mid + 1 # look for the last (rightmost) element satisfying the condition 12 | else: 13 | R = mid - 1 14 | return ans 15 | 16 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/22-subarray-sum-equals-k.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int subarraySum(vector& nums, int k) { 4 | // subarray[L..R] = pref[R] - pref[L-1] 5 | int n = nums.size(); 6 | int answer = 0; 7 | int pref = 0; 8 | unordered_map countPref; 9 | countPref[pref]++; 10 | for(int R = 0; R < n; R++) { 11 | // pref[R]-pref[L-1]=k 12 | //pref[L-1]=pref[R]-k 13 | pref += nums[R]; 14 | int need = pref - k; 15 | answer += countPref[need]; 16 | countPref[pref]++; 17 | } 18 | return answer; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /templates/ordered_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include 5 | template > 6 | using ordered_map = __gnu_pbds::tree< 7 | K, V, Comp, 8 | __gnu_pbds::rb_tree_tag, 9 | __gnu_pbds::tree_order_statistics_node_update 10 | >; // from ecnerwala's library 11 | template > 12 | using ordered_set = ordered_map; 13 | 14 | int main(){ 15 | ordered_set s; 16 | s.insert(20); 17 | s.insert(50); 18 | cout << s.order_of_key(60) << endl; // count elements smaller than 60 19 | cout << *s.find_by_order(1) << endl; // element with index 1 20 | } 21 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/18-minimum-path-sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minPathSum(vector>& grid) { 4 | int H = grid.size(); 5 | int W = grid[0].size(); 6 | vector> dp(H, vector(W)); 7 | for(int row = 0; row < H; ++row) { 8 | for(int col = 0; col < W; ++col) { 9 | if(row == 0 && col == 0) { 10 | dp[row][col] = grid[row][col]; 11 | } 12 | else { 13 | dp[row][col] = grid[row][col] + min((row==0?INT_MAX:dp[row-1][col]), (col==0?INT_MAX:dp[row][col-1])); 14 | } 15 | } 16 | } 17 | return dp[H-1][W-1]; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /CSES/Introductory/13-gray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // O(N * 2^N) 5 | 6 | vector solve(int n) { 7 | if (n == 1) { 8 | return {"0", "1"}; 9 | } 10 | vector a = solve(n-1); 11 | vector b = a; 12 | reverse(b.begin(), b.end()); 13 | for (string& s : a) { 14 | s += '0'; 15 | } 16 | for (string& s : b) { 17 | s += '1'; 18 | } 19 | a.insert(a.end(), b.begin(), b.end()); 20 | return a; 21 | } 22 | 23 | int main() { 24 | int n; 25 | cin >> n; 26 | vector answer = solve(n); 27 | for (string s : answer) { 28 | cout << s << "\n"; 29 | } 30 | } 31 | 32 | 33 | // n = 3 34 | // 000 35 | // 001 36 | // 011 37 | // 010 38 | // 110 39 | // 111 40 | // 101 41 | // 100 42 | -------------------------------------------------------------------------------- /lectures/binary-search/find-minimum-in-rotated-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | // Find Minimum in Rotated Sorted Array, https://leetcode.com/explore/learn/card/binary-search/126/template-ii/949/ 2 | 3 | class Solution { 4 | public: 5 | int findMin(vector& a) { 6 | int n = a.size(); 7 | int left = 0, right = n - 1; 8 | int ans = -1; 9 | while(left <= right) { 10 | int mid = left + (right - left) / 2; 11 | if(a[mid] <= a[n-1]) { 12 | ans = a[mid]; 13 | right = mid - 1; // look for something even smaller on the left 14 | } 15 | else { 16 | left = mid + 1; 17 | } 18 | } 19 | return ans; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /AOC-2024/04-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const vector> dirs = {{-1,-1},{-1,1},{1,1},{1,-1}}; // order important 5 | 6 | int main() { 7 | int H = 140; 8 | vector a(H); 9 | for (string& row : a) { 10 | cin >> row; 11 | } 12 | int W = (int) a[0].length(); 13 | 14 | int answer = 0; 15 | for (int row = 1; row < H - 1; row++) { 16 | for (int col = 1; col < W - 1; col++) { 17 | if (a[row][col] == 'A') { 18 | string s; 19 | for (pair dir : dirs) { 20 | s += a[row+dir.first][col+dir.second]; 21 | } 22 | if (s == "MMSS" || s == "MSSM" || s == "SSMM" || s == "SMMS") { 23 | answer++; 24 | } 25 | } 26 | } 27 | } 28 | cout << answer << "\n"; 29 | } 30 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/16-valid-varenthesis-string.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool checkValidString(string s) { 4 | int n = s.length(); 5 | int balance = 0; 6 | for(int i = 0; i < n; i++) { 7 | if(s[i] == '(' || s[i] == '*') { 8 | balance++; 9 | } 10 | else if(--balance == -1) { 11 | return false; 12 | } 13 | } 14 | balance = 0; 15 | for(int i = n - 1; i >= 0; i--) { 16 | if(s[i] == ')' || s[i] == '*') { 17 | balance++; 18 | } 19 | else if(--balance == -1) { 20 | return false; 21 | } 22 | } 23 | return true; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /lectures/binary-search/find-minimum-in-rotated-sorted-array.py: -------------------------------------------------------------------------------- 1 | # Find Minimum in Rotated Sorted Array, https://leetcode.com/explore/learn/card/binary-search/126/template-ii/949/ 2 | 3 | class Solution: 4 | def findMin(self, a: List[int]) -> int: 5 | n = len(a) 6 | left, right = 0, len(a) - 1 7 | ans = -1 # this value won't be returned anyway because there are some elements satisfying the condition "smaller/equal than the last element" 8 | while left <= right: 9 | mid = left + (right - left) // 2 10 | if a[mid] <= a[n-1]: 11 | ans = a[mid] 12 | right = mid - 1 # look for something even smaller on the left 13 | else: 14 | left = mid + 1; 15 | return ans 16 | -------------------------------------------------------------------------------- /AOC-2020/13-search/shuttle2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector read() { 5 | int start; 6 | cin >> start; 7 | string s; 8 | cin >> s; 9 | vector a{0}; 10 | for(int i = 0; i < (int) s.length(); ++i) { 11 | if(s[i] == ',') { 12 | a.push_back(0); 13 | } 14 | if(isdigit(s[i])) { 15 | a.back() = 10 * a.back() + (s[i] - '0'); 16 | } 17 | } 18 | return a; 19 | } 20 | 21 | int main() { 22 | vector buses = read(); // every x is replaced with 0 23 | long long t = 0; 24 | long long product = 1; 25 | for(int i = 0; i < (int) buses.size(); ++i) { 26 | if(buses[i] != 0) { 27 | while((t + i) % buses[i] != 0) { 28 | t += product; 29 | } 30 | product *= buses[i]; 31 | } 32 | } 33 | printf("%lld\n", t); 34 | } 35 | -------------------------------------------------------------------------------- /lectures/binary-search/first-bad-version.py: -------------------------------------------------------------------------------- 1 | # First Bad Version, https://leetcode.com/explore/learn/card/binary-search/126/template-ii/947/ 2 | 3 | # The isBadVersion API is already defined for you. 4 | # @param version, an integer 5 | # @return a bool 6 | # def isBadVersion(version): 7 | 8 | class Solution: 9 | def firstBadVersion(self, n): 10 | left, right = 1, n 11 | ans = -1 # returned if there is no bad version (impossible in this problem though) 12 | while left <= right: 13 | mid = left + (right - left) // 2 14 | if isBadVersion(mid): 15 | ans = mid 16 | right = mid - 1 # maybe there is even ealier bad version on the left 17 | else : 18 | left = mid + 1 19 | return ans 20 | 21 | -------------------------------------------------------------------------------- /testing/info.txt: -------------------------------------------------------------------------------- 1 | You are given a sequence of DISTINCT numbers a[1], a[2], ..., a[N]. 2 | Find the second smallest element in the sequence. 3 | 2 <= N <= 10^6, 1 <= a[i] <= 10^9 4 | 5 | a.cpp - incorrect solution 6 | brute.cpp - correct slow solution 7 | in - sample input 8 | gen.cpp - test generator 9 | s.sh - script that tests a.cpp and brute.cpp against each other 10 | 11 | gen_tree.cpp - stupid tree generator 12 | gen_tree2.cpp - better tree generator 13 | Read about Prufer sequences for even smarter tree generation. 14 | 15 | My compilation flags: 16 | 17 | 1) fast running time 18 | g++ -O2 -std=c++17 -Wno-unused-result -Wshadow -Wall -o a a.cpp 19 | 20 | 2) check for mistakes 21 | g++ -std=c++17 -Wshadow -Wall -o a a.cpp 22 | -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG -g 23 | -------------------------------------------------------------------------------- /pairs/ac.py: -------------------------------------------------------------------------------- 1 | def isOk(x,y,data): 2 | for datax,datay in data: 3 | if datax != x and datay != x and datax!=y and datay!=y: 4 | return False 5 | return True 6 | 7 | 8 | 9 | def findCommonPair(data): 10 | for i in data[0]: 11 | if isOk(i,-1,data): 12 | return 'yes'+str(i)+str(-1) 13 | 14 | for x,y in data[1:]: 15 | if i!=x or i!=y: 16 | for j in (x,y): 17 | print(j,'::',isOk(i,j,data)) 18 | if isOk(i,j,data): 19 | return 'yes'+str(i)+str(j) 20 | 21 | 22 | return 'NO' 23 | 24 | 25 | 26 | data=[[4,2],[2,4],[4,7],[7,4],[4,0],[4,9],[4,2]] 27 | print(findCommonElement(data)) 28 | -------------------------------------------------------------------------------- /CSES/Introductory/07-two-knights.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int max_n; 6 | cin >> max_n; 7 | // O(N) 8 | // it's magic that it works for n <= 3 9 | for (long long n = 1; n <= max_n; n++) { 10 | long long size = n * n; 11 | long long allWays = size * (size - 1) / 2; 12 | long long badWays = 0; 13 | badWays += 8 * (n-4) * (n-4); 14 | badWays += 6 * (n-4) * 4; 15 | badWays += 4 * (n-3) * 4; 16 | badWays += 3 * 8; 17 | badWays += 2 * 4; 18 | badWays /= 2; 19 | cout << allWays - badWays << "\n"; 20 | } 21 | } 22 | 23 | // 234444444444432 24 | // 346666666666643 25 | // 468888888888864 26 | // 468888888888864 27 | // 468888888888864 28 | // 468888888888864 29 | // 468888888888864 30 | // 468888888888864 31 | // 346666666666643 32 | // 234444444444432 33 | -------------------------------------------------------------------------------- /lectures/binary-search/first-bad-version.cpp: -------------------------------------------------------------------------------- 1 | // First Bad Version, https://leetcode.com/explore/learn/card/binary-search/126/template-ii/947/ 2 | 3 | // Forward declaration of isBadVersion API. 4 | bool isBadVersion(int version); 5 | 6 | class Solution { 7 | public: 8 | int firstBadVersion(int n) { 9 | int left = 1, right = n; 10 | int ans = -1; // returned if there is no bad version (impossible in this problem though) 11 | while(left <= right) { 12 | int mid = left + (right - left) / 2; 13 | if(isBadVersion(mid)) { 14 | ans = mid; 15 | right = mid - 1; // maybe there is even ealier bad version on the left 16 | } 17 | else { 18 | left = mid + 1; 19 | } 20 | } 21 | return ans; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /AOC-2024/13.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | char s[105]; 5 | int answer = 0; 6 | while (scanf("%s", s) != EOF) { 7 | scanf(" %s", s); 8 | int ax, ay, bx, by; 9 | scanf(" X+%d, ", &ax); 10 | scanf(" Y+%d", &ay); 11 | scanf(" %s", s); 12 | scanf(" %s", s); 13 | scanf(" X+%d, ", &bx); 14 | scanf(" Y+%d", &by); 15 | scanf(" %s", s); 16 | int px, py; 17 | scanf(" X=%d, ", &px); 18 | scanf(" Y=%d", &py); 19 | printf("%d %d\n", ax, ay); 20 | printf("%d %d\n", bx, by); 21 | for (int i = 0; i * ax <= px; i++) { 22 | assert(bx != 0); 23 | int j = (px - i * ax) / bx; 24 | if (i * ax + j * bx == px) { 25 | if (i * ay + j * by == py) { 26 | assert(i <= 100 && j <= 100); 27 | answer += 3 * i + j; 28 | } 29 | } 30 | } 31 | } 32 | printf("%d\n", answer); 33 | } 34 | -------------------------------------------------------------------------------- /AOC-2024/02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | int main() { 6 | int n = 1000; 7 | int answer = 0; 8 | for (int i = 0; i < n; i++) { 9 | vector a; 10 | while (true) { 11 | int x; 12 | scanf("%d", &x); 13 | a.push_back(x); 14 | char c; 15 | scanf("%c", &c); 16 | if (c == '\n') { 17 | break; 18 | } 19 | } 20 | int k = (int) a.size(); 21 | bool ok = true; 22 | bool only_inc = true; 23 | bool only_dec = true; 24 | for (int j = 0; j < k - 1; j++) { 25 | int diff = a[j+1] - a[j]; 26 | if (diff > 0) { 27 | only_dec = false; 28 | } 29 | if (diff < 0) { 30 | only_inc = false; 31 | } 32 | if (!(1 <= abs(diff) && abs(diff) <= 3)) { 33 | ok = false; 34 | break; 35 | } 36 | } 37 | if (ok && (only_inc || only_dec)) { 38 | answer++; 39 | } 40 | } 41 | printf("%d\n", answer); 42 | } 43 | -------------------------------------------------------------------------------- /lectures/binary-search/guess-number.py: -------------------------------------------------------------------------------- 1 | # Guess Number Higher or Lower, https://leetcode.com/explore/learn/card/binary-search/125/template-i/951/ 2 | 3 | # The guess API is already defined for you. 4 | # @param num, your guess 5 | # @return -1 if my number is lower, 1 if my number is higher, otherwise return 0 6 | # def guess(num): 7 | 8 | class Solution(object): 9 | def guessNumber(self, n): 10 | left = 1 11 | right = n 12 | while left <= right: 13 | mid = left + (right - left) // 2 14 | x = guess(mid) # let's remember this value not to repeat the query in ifs below 15 | if x == 0: 16 | return mid 17 | if x == 1: 18 | left = mid + 1 19 | else: 20 | right = mid - 1 21 | assert False # we shouldn't get here because it's guaranteed the target value is in the array 22 | -------------------------------------------------------------------------------- /leetcode/21-merge-two-sorted-lists.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/merge-two-sorted-lists/ 2 | // video tutorial: https://youtu.be/EvgZCUhTosc 3 | class Solution { 4 | public: 5 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 6 | ListNode fake(-1); 7 | ListNode* last = &fake; 8 | while(l1 != NULL && l2 != NULL) { 9 | if(l1->val < l2->val) { 10 | last->next = l1; 11 | last = l1; 12 | l1 = l1->next; // time: O(N+M) space: O(1) 13 | } 14 | else { 15 | last->next = l2; 16 | last = l2; 17 | l2 = l2->next; 18 | } 19 | } 20 | if(l1 != NULL) { 21 | last->next = l1; 22 | } 23 | if(l2 != NULL) { 24 | last->next = l2; 25 | } 26 | return fake.next; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /two-arrays-and-sum-of-functions/ac.cpp: -------------------------------------------------------------------------------- 1 | // E. Two Arrays and Sum of Functions, CF #560 (Div. 3) 2 | // https://codeforces.com/contest/1165/problem/E 3 | // O(n*log(n)) 4 | #include 5 | using namespace std; 6 | const int MOD = 998244353; 7 | int main() { 8 | int n; 9 | scanf("%d", &n); 10 | vector a(n); 11 | for(int i = 0; i < n; ++i) { 12 | scanf("%lld", &a[i]); 13 | a[i] = a[i] * (i + 1) * (n - i); 14 | // don't apply modulo here because sort would be incorrect! 15 | } 16 | vector b(n); 17 | for(int i = 0; i < n; ++i) { 18 | scanf("%d", &b[i]); 19 | } 20 | sort(a.begin(), a.end()); // sort increasingly 21 | sort(b.rbegin(), b.rend()); // sort decreasingly 22 | int answer = 0; 23 | for(int i = 0; i < n; ++i) { 24 | a[i] %= MOD; // to avoid overflow in multiplication 25 | answer = (answer + a[i] * b[i]) % MOD; 26 | } 27 | printf("%d\n", answer); 28 | } 29 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/11-diameter-of-binary-tree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | * }; 9 | */ 10 | 11 | class Solution { 12 | pair dfs(TreeNode* root) { 13 | // (diameter, depth) 14 | if(root == NULL) { 15 | return {0, 0}; 16 | } 17 | pair left = dfs(root->left); 18 | pair right = dfs(root->right); 19 | int diam = max({left.first, right.first, left.second + right.second}); 20 | return {diam, max(left.second, right.second) + 1}; 21 | } 22 | 23 | public: 24 | int diameterOfBinaryTree(TreeNode* root) { 25 | return dfs(root).first; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /matrix-exponentiation/c2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int mod = 1e9 + 7; 4 | struct M { 5 | int a[2][2] = {{0, 0}, {0, 0}}; 6 | M operator *(const M& other) const { 7 | M product; 8 | for(int i : {0, 1}) { 9 | for(int j : {0, 1}) { 10 | for(int k : {0, 1}) { 11 | product.a[i][k] = (product.a[i][k] 12 | + (long long) a[i][j] * other.a[j][k]) % mod; 13 | } 14 | } 15 | } 16 | return product; 17 | } 18 | }; 19 | M expo_power(M a, long long n) { 20 | M res; 21 | res.a[0][0] = res.a[1][1] = 1; 22 | while(n) { 23 | if(n % 2) { 24 | res = res * a; 25 | } 26 | n /= 2; 27 | a = a * a; 28 | } 29 | return res; 30 | } 31 | int main() { 32 | long long n; 33 | cin >> n; 34 | M single; 35 | single.a[0][0] = 0; 36 | single.a[0][1] = 1; 37 | single.a[1][0] = 1; 38 | single.a[1][1] = 1; 39 | cout << expo_power(single, n).a[1][0] << endl; 40 | } 41 | -------------------------------------------------------------------------------- /AOC-2024/23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | char s[7]; 5 | set nodes; 6 | map> edges; // adjacency list 7 | set> pairs; // set of edges 8 | // not using: adjacency matrix 9 | while (scanf("%s", s) != EOF) { 10 | // printf("> %s\n", s); 11 | string a(s, s + 2); 12 | string b(s + 3, s + 5); 13 | 14 | nodes.insert(a); 15 | nodes.insert(b); 16 | edges[a].push_back(b); 17 | edges[b].push_back(a); 18 | pairs.insert({a,b}); 19 | pairs.insert({b,a}); 20 | } 21 | 22 | int answer = 0; 23 | for (string a : nodes) { 24 | for (string b : edges[a]) { 25 | for (string c : edges[b]) { 26 | if (pairs.count({a,c})) { 27 | if (a[0] == 't' || b[0] == 't' || c[0] == 't') { 28 | answer++; 29 | } 30 | } 31 | } 32 | } 33 | } 34 | assert(answer % 6 == 0); 35 | printf("%d\n", answer / 6); 36 | } 37 | -------------------------------------------------------------------------------- /CSES/Introductory/16-apple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int n; 5 | int a[21]; 6 | long long answer = LONG_LONG_MAX; 7 | 8 | // O(2^N) 9 | // f(next_index, sum_of_first_set, sum_of_second_set) 10 | // f(next_index, sumFirst - sumSecond) 11 | void f(int i, long long diff) { 12 | if (i == n) { 13 | answer = min(answer, abs(diff)); 14 | return; 15 | } 16 | f(i+1, diff + a[i]); 17 | f(i+1, diff - a[i]); 18 | } 19 | 20 | int main() { 21 | cin >> n; 22 | for (int i = 0; i < n; i++) { 23 | cin >> a[i]; 24 | } 25 | f(0, 0); 26 | cout << answer << "\n"; 27 | // O(2^N * N) 28 | // for (int mask = 0; mask < (1 << n); mask++) { 29 | // long long diff = 0; 30 | // for (int i = 0; i < n; i++) { 31 | // if (mask & (1 << i)) { 32 | // diff += a[i]; 33 | // } 34 | // else { 35 | // diff -= a[i]; 36 | // } 37 | // } 38 | // answer = min(answer, abs(diff)); 39 | // } 40 | } 41 | -------------------------------------------------------------------------------- /AOC-2024/09-easy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct Block { 5 | int id, size, pos; 6 | }; 7 | 8 | int main() { 9 | string s; 10 | cin >> s; 11 | int n = s.length(); 12 | vector v; 13 | vector avail; 14 | for (int i = 0; i < n; i++) { 15 | int digit = s[i] - '0'; 16 | for (int rep = 0; rep < digit; rep++) { 17 | if (i % 2 == 0) { 18 | v.push_back(i / 2); 19 | } 20 | else { 21 | avail.push_back(v.size()); 22 | v.push_back(0); 23 | } 24 | } 25 | } 26 | reverse(avail.begin(), avail.end()); 27 | for (int i = (int) v.size() - 1; i >= 0; i--) { 28 | if (v[i]) { 29 | if (!avail.empty() && avail.back() < i) { 30 | v[avail.back()] = v[i]; 31 | v[i] = 0; 32 | avail.pop_back(); 33 | } 34 | } 35 | } 36 | 37 | long long answer = 0; 38 | for (int i = 0; i < (int) v.size(); i++) { 39 | answer += v[i] * i; 40 | } 41 | cout << answer << "\n"; 42 | } 43 | -------------------------------------------------------------------------------- /CSES/Introductory/19-mex-grid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // There are N piles of stones, i-th has a[i] stones. 5 | // There are two players. Each can take any nonnegative numbers of stones from a pile. 6 | // If piles are empty and you cannot make a move, you lose. 7 | // Who will win? 8 | 9 | int main() { 10 | int n; 11 | cin >> n; 12 | // vector> a(n, vector(n)); // O(N^3 * log(N)) 13 | for (int row = 0; row < n; row++) { 14 | for (int col = 0; col < n; col++) { 15 | cout << (row ^ col) << " "; 16 | // set s; 17 | // for (int r = 0; r < row; r++) { 18 | // s.insert(a[r][col]); 19 | // } 20 | // for (int c = 0; c < col; c++) { 21 | // s.insert(a[row][c]); 22 | // } 23 | // int x = 0; 24 | // while (s.count(x)) { 25 | // x++; 26 | // } 27 | // a[row][col] = x; 28 | // cout << a[row][col] << " "; 29 | } 30 | cout << "\n"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/02-happy-number.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int f(int n) { // log(N) 3 | int sum = 0; 4 | while(n) { 5 | int digit = n % 10; 6 | n /= 10; 7 | sum += digit * digit; 8 | } 9 | return sum; 10 | } 11 | public: 12 | bool isHappy(int n) { 13 | for(int rep = 0; rep < 20; rep++) { 14 | n = f(n); 15 | if(n == 1) { 16 | return true; 17 | } 18 | } 19 | return false; 20 | } 21 | /* 22 | unordered_set visited; 23 | for(int rep = 0; rep < 20; ++rep) { 24 | if(n == 1) { 25 | return true; 26 | } 27 | n = f(n); 28 | if(visited.count(n) == 1) { 29 | return false; 30 | } 31 | visited.insert(n); 32 | } 33 | assert(false); 34 | }*/ 35 | }; 36 | -------------------------------------------------------------------------------- /AOC-2024/18.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int INF = 1e9 + 5; 5 | 6 | const int S = 71; 7 | bool vis[S][S]; 8 | 9 | int main() { 10 | for (int i = 0; i < 1024; i++) { 11 | int x, y; 12 | scanf(" %d,%d", &x, &y); 13 | vis[x][y] = true; 14 | } 15 | assert(!vis[0][0]); 16 | vector> dist(S, vector(S, INF)); 17 | vector> q; 18 | q.emplace_back(0, 0); 19 | dist[0][0] = 0; 20 | vis[0][0] = true; 21 | for (int i = 0; i < (int) q.size(); i++) { 22 | int r = q[i].first; 23 | int c = q[i].second; 24 | for (pair dir : vector>{{-1,0},{1,0},{0,1},{0,-1}}) { 25 | int r2 = r + dir.first; 26 | int c2 = c + dir.second; 27 | if (0 <= min(r2, c2) && max(r2, c2) < S && !vis[r2][c2]) { 28 | vis[r2][c2] = true; 29 | dist[r2][c2] = dist[r][c] + 1; 30 | q.emplace_back(r2, c2); 31 | } 32 | } 33 | } 34 | printf("%d\n", dist[S-1][S-1]); 35 | } 36 | -------------------------------------------------------------------------------- /AOC-2024/06.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector> dirs = {{-1,0}, {0,1}, {1,0}, {0,-1}}; 5 | 6 | int main() { 7 | int H = 130; 8 | vector a(H); 9 | for (int i = 0; i < H; i++) { 10 | cin >> a[i]; 11 | } 12 | int W = a[0].length(); 13 | 14 | pair me{-1, -1}; 15 | int dir = 0; 16 | for (int row = 0; row < H; row++) { 17 | for (int col = 0; col < W; col++) { 18 | if (a[row][col] == '^') { 19 | me = {row, col}; 20 | a[row][col] = '.'; 21 | } 22 | } 23 | } 24 | set> vis; 25 | while (true) { 26 | vis.insert(me); 27 | int r2 = me.first + dirs[dir].first; 28 | int c2 = me.second + dirs[dir].second; 29 | if (!(0 <= r2 && r2 < H && 0 <= c2 && c2 < W)) { 30 | break; // outside 31 | } 32 | if (a[r2][c2] == '.') { 33 | me = {r2, c2}; 34 | } 35 | else { 36 | dir = (dir + 1) % 4; 37 | } 38 | } 39 | cout << vis.size() << "\n"; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /matrix-exponentiation/a.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define REP(i,n) for(int i = 0; i < (n); i++) 4 | struct Matrix { 5 | double a[2][2] = {{0,0},{0,0}}; 6 | Matrix operator *(const Matrix& other) { 7 | Matrix product; 8 | REP(i,2)REP(j,2)REP(k,2) { 9 | product.a[i][k] += a[i][j] * other.a[j][k]; 10 | } 11 | return product; 12 | } 13 | }; 14 | Matrix expo_power(Matrix a, int k) { 15 | Matrix product; 16 | REP(i,2) product.a[i][i] = 1; 17 | while(k > 0) { 18 | if(k % 2) { 19 | product = product * a; 20 | } 21 | a = a * a; 22 | k /= 2; 23 | } 24 | return product; 25 | } 26 | int main() { 27 | // A. Random Mood 28 | int n; 29 | double p; 30 | cin >> n >> p; 31 | Matrix single; 32 | single.a[0][0] = 1 - p; 33 | single.a[0][1] = p; 34 | single.a[1][0] = p; 35 | single.a[1][1] = 1 - p; 36 | Matrix total = expo_power(single, n); 37 | cout << setprecision(10) << fixed << total.a[0][0] << endl; 38 | } 39 | -------------------------------------------------------------------------------- /lectures/binary-search/guess-number.cpp: -------------------------------------------------------------------------------- 1 | // Guess Number Higher or Lower, https://leetcode.com/explore/learn/card/binary-search/125/template-i/951/ 2 | 3 | // Forward declaration of guess API. 4 | // @param num, your guess 5 | // @return -1 if my number is lower, 1 if my number is higher, otherwise return 0 6 | int guess(int num); 7 | 8 | class Solution { 9 | public: 10 | int guessNumber(int n) { 11 | int left = 1, right = n; 12 | while(left <= right) { 13 | int mid = left + (right - left) / 2; 14 | int x = guess(mid); // let's remember this value not to repeat the query in ifs below 15 | if(x == 0) { 16 | return mid; 17 | } 18 | if(x == 1) { 19 | left = mid + 1; 20 | } 21 | else { // x == -1 22 | right = mid - 1; 23 | } 24 | } 25 | assert(false); // we shouldn't get here 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/27-maximal-square.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maximalSquare(vector>& matrix) { 4 | int H = matrix.size(); 5 | if(H == 0 || matrix[0].empty()) { 6 | return 0; 7 | } 8 | int W = matrix[0].size(); 9 | vector> dp(H, vector(W)); 10 | int answer = 0; 11 | // dp[r][c] - best square ending at (r, c) 12 | for(int row = 0; row < H; ++row) { 13 | for(int col = 0; col < W; ++col) { 14 | if(matrix[row][col] == '1') { 15 | dp[row][col] = 1; 16 | if(row > 0 && col > 0) { 17 | dp[row][col] += min({dp[row-1][col], dp[row][col-1], dp[row-1][col-1]}); 18 | } 19 | answer = max(answer, dp[row][col]); 20 | } 21 | } 22 | } 23 | return answer * answer; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /CSES/Introductory/17-chessboard.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | long long answer = 0; 5 | vector grid(8); 6 | bool colAttacked[8]; 7 | bool diagSum[15], diagDiff[15]; 8 | 9 | // backtracking 10 | 11 | // O(N! * N) but way faster in practice because of diagonals 12 | void place(int row) { 13 | if (row == 8) { 14 | answer++; 15 | return; 16 | } 17 | for (int col = 0; col < 8; col++) { 18 | if (grid[row][col] == '.' && !colAttacked[col] && !diagSum[row+col] && !diagDiff[row-col+7]) { 19 | // grid[row][col] = 'Q'; 20 | colAttacked[col] = true; 21 | diagSum[row+col] = true; 22 | diagDiff[row-col+7] = true; 23 | place(row+1); 24 | colAttacked[col] = false; 25 | diagSum[row+col] = false; 26 | diagDiff[row-col+7] = false; 27 | // grid[row][col] = '.'; 28 | } 29 | } 30 | } 31 | 32 | int main() { 33 | for (string& s : grid) { 34 | cin >> s; 35 | } 36 | place(0); 37 | cout << answer << "\n"; 38 | } 39 | -------------------------------------------------------------------------------- /matrix-exponentiation/c.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define REP(i,n) for(int i = 0; i < (n); i++) 4 | const int mod = 1e9 + 7; 5 | struct Matrix { 6 | int a[2][2] = {{0,0},{0,0}}; 7 | Matrix operator *(const Matrix& other) { 8 | Matrix product; 9 | REP(i,2)REP(j,2)REP(k,2) { 10 | product.a[i][k] = (product.a[i][k] + (long long) a[i][j] * other.a[j][k]) % mod; 11 | } 12 | return product; 13 | } 14 | }; 15 | Matrix expo_power(Matrix a, long long k) { 16 | Matrix product; 17 | REP(i,2) product.a[i][i] = 1; 18 | while(k > 0) { 19 | if(k % 2) { 20 | product = product * a; 21 | } 22 | a = a * a; 23 | k /= 2; 24 | } 25 | return product; 26 | } 27 | int main() { 28 | // C. Fibonacci 29 | long long n; 30 | cin >> n; 31 | Matrix single; 32 | single.a[0][0] = 0; 33 | single.a[0][1] = 1; 34 | single.a[1][0] = 1; 35 | single.a[1][1] = 1; 36 | Matrix total = expo_power(single, n); 37 | cout << total.a[1][0] << endl; 38 | } 39 | -------------------------------------------------------------------------------- /CSES/Introductory/20-knight-moves.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // BFS on a grid 5 | 6 | const int INF = 1e9 + 5; 7 | vector> dirs = {{-2,-1},{-2,1},{-1,2},{-1,-2},{1,-2},{1,2},{2,-1},{2,1}}; 8 | 9 | // O(N^2 * 8) 10 | 11 | int main() { 12 | int n; 13 | cin >> n; 14 | vector> dist(n, vector(n, INF)); 15 | vector> q; 16 | q.emplace_back(0, 0); 17 | dist[0][0] = 0; 18 | for (int i = 0; i < (int) q.size(); i++) { 19 | auto [row, col] = q[i]; 20 | for (pair dir : dirs) { 21 | int r2 = row + dir.first; 22 | int c2 = col + dir.second; 23 | if (0 <= min(r2, c2) && max(r2, c2) < n && dist[r2][c2] == INF) { 24 | dist[r2][c2] = dist[row][col] + 1; 25 | q.emplace_back(r2, c2); 26 | } 27 | } 28 | } 29 | 30 | for (int row = 0; row < n; row++) { 31 | for (int col = 0; col < n; col++) { 32 | cout << dist[row][col] << " "; 33 | } 34 | cout << "\n"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /matrix-exponentiation/b.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define REP(i,n) for(int i = 0; i < (n); i++) 4 | const int mod = 1e9 + 7; 5 | struct Matrix { 6 | int a[2][2] = {{0,0},{0,0}}; 7 | Matrix operator *(const Matrix& other) { 8 | Matrix product; 9 | REP(i,2)REP(j,2)REP(k,2) { 10 | product.a[i][k] = (product.a[i][k] + (long long) a[i][j] * other.a[j][k]) % mod; 11 | } 12 | return product; 13 | } 14 | }; 15 | Matrix expo_power(Matrix a, long long k) { 16 | Matrix product; 17 | REP(i,2) product.a[i][i] = 1; 18 | while(k > 0) { 19 | if(k % 2) { 20 | product = product * a; 21 | } 22 | a = a * a; 23 | k /= 2; 24 | } 25 | return product; 26 | } 27 | int main() { 28 | // B. String Mood 29 | long long n; 30 | cin >> n; 31 | Matrix single; 32 | single.a[0][0] = 19; 33 | single.a[0][1] = 7; 34 | single.a[1][0] = 6; 35 | single.a[1][1] = 20; 36 | Matrix total = expo_power(single, n); 37 | cout << total.a[0][0] << endl; 38 | } 39 | -------------------------------------------------------------------------------- /CSES/Introductory/22-digit-queries.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // O(T*log(K)) 5 | void test_case() { 6 | long long k; 7 | cin >> k; 8 | long long cnt = 9; // number of numbers of this length 9 | long long skipped = 0; 10 | for (int len = 1; true; len++) { 11 | if (k > len * cnt) { 12 | k -= len * cnt; 13 | skipped += cnt; 14 | } 15 | else { 16 | long long skip = (k-1) / len; 17 | skipped += skip; 18 | k -= skip * len; 19 | 20 | long long x = skipped + 1; 21 | cout << to_string(x)[k-1] << "\n"; 22 | return; 23 | } 24 | cnt *= 10; 25 | } 26 | // 9 x 1 27 | // 90 x 2 <-- 90 numbers with 2 digits each 28 | // 900 x 3 29 | // 9000 x 4 30 | // ... 31 | } 32 | 33 | int main() { 34 | int T; 35 | cin >> T; 36 | for (int rep = 0; rep < T; rep++) { 37 | test_case(); 38 | } 39 | } 40 | // 123456789 10 11 12 13 14 1516171819202122232425 41 | // <-------> ^ 42 | // 9 k=20 43 | -------------------------------------------------------------------------------- /AOC-2024/07.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | void rec(int i, long long sum, long long target, const vector& v, bool& ok) { 6 | if (i == (int) v.size()) { 7 | if (sum == target) { 8 | ok = true; 9 | } 10 | return; 11 | } 12 | rec(i + 1, sum + v[i], target, v, ok); 13 | rec(i + 1, sum * v[i], target, v, ok); 14 | rec(i + 1, stoll(to_string(sum) + to_string(v[i])), target, v, ok); 15 | } 16 | 17 | int main() { 18 | long long res; 19 | long long total_answer = 0; 20 | while (scanf("%lld: ", &res) != EOF) { 21 | vector v; 22 | while (true) { 23 | int x; 24 | scanf("%d", &x); 25 | v.push_back(x); 26 | char c; 27 | scanf("%c", &c); 28 | if (c == ' ') { 29 | continue; 30 | } 31 | else { 32 | break; 33 | } 34 | } 35 | // cout << res << " "; 36 | bool ok = false; 37 | rec(1, v[0], res, v, ok); 38 | if (ok) { 39 | total_answer += res; 40 | } 41 | } 42 | printf("%lld\n", total_answer); 43 | } 44 | -------------------------------------------------------------------------------- /partition-into-permutations/ac.cpp: -------------------------------------------------------------------------------- 1 | // O(N log(N)) 2 | #include 3 | using namespace std; 4 | void test_case() { 5 | int n; 6 | scanf("%d", &n); 7 | vector cnt(2 * n + 1); 8 | int must_remove = 0; 9 | for(int i = 0; i < n; ++i) { 10 | int x; 11 | scanf("%d", &x); 12 | if(x <= 2 * n) { 13 | ++cnt[x]; 14 | } 15 | else { 16 | ++must_remove; 17 | } 18 | } 19 | vector dp(2 * n + 1); 20 | for(int value = 1; value <= 2 * n; ++value) { 21 | vector dp2(2 * n / value + 1); 22 | int suffix_min = dp.back(); 23 | for(int i = (int) dp.size() - 1; i >= 0; --i) { 24 | suffix_min = min(suffix_min, dp[i]); 25 | if(i < (int) dp2.size()) { 26 | dp2[i] = suffix_min + abs(i - cnt[value]); 27 | } 28 | } 29 | dp = dp2; 30 | } 31 | int answer = INT_MAX; 32 | for(int x : dp) { 33 | answer = min(answer, x); 34 | } 35 | printf("%d\n", answer + must_remove); 36 | } 37 | int main() { 38 | int T; 39 | scanf("%d", &T); 40 | while(T--) { 41 | test_case(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /testing/gen_tree2.cpp: -------------------------------------------------------------------------------- 1 | // generating a tree in a not-so-stupid way 2 | #include 3 | using namespace std; 4 | 5 | int rand(int a, int b) { 6 | return a + rand() % (b - a + 1); 7 | } 8 | 9 | int main(int argc, char* argv[]) { 10 | srand(atoi(argv[1])); 11 | int n = rand(2, 20); 12 | printf("%d\n", n); 13 | vector> edges; 14 | for(int i = 2; i <= n; ++i) { 15 | edges.emplace_back(rand(1, i - 1), i); 16 | } 17 | 18 | vector perm(n + 1); // re-naming vertices 19 | for(int i = 1; i <= n; ++i) { 20 | perm[i] = i; 21 | } 22 | random_shuffle(perm.begin() + 1, perm.end()); 23 | 24 | random_shuffle(edges.begin(), edges.end()); // random order of edges 25 | 26 | for(pair edge : edges) { 27 | int a = edge.first, b = edge.second; 28 | if(rand() % 2) { 29 | swap(a, b); // random order of two vertices 30 | } 31 | printf("%d %d\n", perm[a], perm[b]); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /AOC-2024/03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | string s; 6 | char c; 7 | while (scanf("%c", &c) != EOF) { 8 | s += c; 9 | } 10 | s += "###################"; 11 | 12 | int n = (int) s.length(); 13 | 14 | auto getNumber = [&](int& i) { 15 | int x = 0; 16 | while (x < 1000 && isdigit(s[i])) { 17 | x = 10 * x + (s[i] - '0'); 18 | i++; 19 | } 20 | if (1 <= x && x <= 999) { 21 | return x; 22 | } 23 | return -1; 24 | }; 25 | 26 | int answer = 0; 27 | for (int i = 0; i < n; i++) { 28 | if (s[i] == 'm') { 29 | if (s[i+1] == 'u' && s[i+2] == 'l' && s[i+3] == '(') { 30 | i += 4; 31 | int x = getNumber(i); 32 | // cout << i << " " << x << endl; 33 | if (s[i] == ',') { 34 | i += 1; 35 | int y = getNumber(i); 36 | // cout << ">> " << i << " " << x << " " << y << endl; 37 | if (s[i] == ')') { 38 | if (x != -1 && y != -1) { 39 | answer += x * y; 40 | } 41 | } 42 | } 43 | } 44 | } 45 | } 46 | printf("%d\n", answer); 47 | } 48 | -------------------------------------------------------------------------------- /lectures/binary-search/old-implementation.cpp: -------------------------------------------------------------------------------- 1 | // My old implementation of binary search. 2 | 3 | // 1) Looking for 'target' in a sorted array. 4 | int f() { 5 | int left = 0, right = n - 1; 6 | while(left <= right) { 7 | int mid = left + (right - left) / 2; 8 | if(a[mid] == target) { 9 | return mid; 10 | } 11 | else if(a[mid] > target) { 12 | right = mid - 1; 13 | } 14 | else { 15 | left = mid + 1; 16 | } 17 | } 18 | return -1; 19 | } 20 | 21 | // 2) Looking for the index of the first element that satisfies some property. 22 | // F F T T T T <- find first index that has TRUE 23 | int f() { 24 | int left = 0, right = n - 1; // add +1 to 'right' if the answer can be outside [left, right] 25 | while(left < right) { 26 | int mid = left + (right - left) / 2; 27 | if(property(mid)) { 28 | right = mid; 29 | } 30 | else { 31 | left = mid + 1; 32 | } 33 | } 34 | return left; 35 | } 36 | -------------------------------------------------------------------------------- /leetcode/34-find-first-and-last-position-in-sorted.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/ 2 | // video tutorial: https://youtu.be/dVXy6hmE_0U 3 | class Solution { 4 | int first_pos(vector& a, int x) { 5 | int n = a.size(); 6 | int first_pos = n; // first >= x 7 | int low = 0, high = n - 1; 8 | while(low <= high) { 9 | int mid = low + (high - low) / 2; 10 | if(a[mid] >= x) { 11 | first_pos = mid; 12 | high = mid - 1; 13 | } 14 | else { // a[mid] < x 15 | low = mid + 1; 16 | } 17 | } 18 | return first_pos; 19 | } 20 | public: 21 | vector searchRange(vector& a, int x) { 22 | // lower_bound(a.begin(), a.end(), x); 23 | int first = first_pos(a, x); 24 | int last = first_pos(a, x + 1) - 1; 25 | if(first <= last) { 26 | return {first, last}; 27 | } 28 | return {-1, -1}; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /pairs/ac.cpp: -------------------------------------------------------------------------------- 1 | // B. Pairs, CF #562 (Div. 2) 2 | // https://codeforces.com/contest/1169/problem/B 3 | // O(n) 4 | #include 5 | using namespace std; 6 | 7 | vector> pairs; 8 | 9 | bool ok(int x, int y) { 10 | for(pair p : pairs) { 11 | if(p.first != x && p.first != y && p.second != x && p.second != y) { 12 | return false; 13 | } 14 | } 15 | return true; 16 | } 17 | 18 | int main() { 19 | int n, m; 20 | scanf("%d%d", &n, &m); 21 | for(int i = 0; i < m; ++i) { 22 | int a, b; 23 | scanf("%d%d", &a, &b); 24 | pairs.emplace_back(a, b); 25 | } 26 | for(int x : {pairs[0].first, pairs[0].second}) { 27 | if(ok(x, -1)) { // maybe x is enough 28 | puts("YES"); 29 | return 0; 30 | } 31 | for(int i = 1; i < m; ++i) { 32 | if(pairs[i].first != x && pairs[i].second != x) { 33 | // y must be an element of pairs[i] 34 | if(ok(x, pairs[i].first) || ok(x, pairs[i].second)) { 35 | puts("YES"); 36 | return 0; 37 | } 38 | break; // prevents from O(M^2) complexity 39 | } 40 | } 41 | } 42 | puts("NO"); 43 | } 44 | -------------------------------------------------------------------------------- /lectures/binary-search/sqrt.cpp: -------------------------------------------------------------------------------- 1 | // Sqrt(x), https://leetcode.com/explore/learn/card/binary-search/125/template-i/950/ 2 | /* 3 | int f() { 4 | int left = 0, right = n - 1; 5 | int ans = -1; 6 | while(left <= right) { 7 | int mid = left + (right - left) / 2; 8 | if(property(mid)) { 9 | ans = mid; 10 | right = mid - 1; // if we're looking for the first (leftmost element) 11 | } 12 | else { 13 | left = mid + 1; 14 | } 15 | } 16 | return ans; 17 | } 18 | */ 19 | 20 | // Find the last number M that M*M <= x. 21 | 22 | class Solution { 23 | public: 24 | int mySqrt(int x) { 25 | int left = 0, right = x; 26 | int ans = -1; 27 | while(left <= right) { 28 | int mid = left + (right - left) / 2; 29 | if((long long) mid * mid <= x) { 30 | ans = mid; 31 | left = mid + 1; // we're looking for the last element satisfying the condition 32 | } 33 | else { 34 | right = mid - 1; 35 | } 36 | } 37 | return ans; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /PSUT-coding-marathon/templates.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | 35 | 36 | int main() { 37 | 38 | } 39 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/09-backspace-string-compare.cpp: -------------------------------------------------------------------------------- 1 | // This is not the best solution! Read one without modifying input strings in leetcode solution tab: 2 | // https://leetcode.com/problems/backspace-string-compare/solution/ 3 | class Solution { 4 | void remove(string& s, int& len) { 5 | for(int i = 0; i < (int) s.length(); ++i) { 6 | if(s[i] == '#') { 7 | if(len > 0) { 8 | len--; 9 | } 10 | } 11 | else { 12 | s[len] = s[i]; 13 | len++; 14 | } 15 | } 16 | } 17 | public: 18 | bool backspaceCompare(string S, string T) { 19 | int len_s = 0, len_t = 0; 20 | remove(S, len_s); 21 | remove(T, len_t); 22 | if(len_s != len_t) { 23 | return false; 24 | } 25 | for(int i = 0; i < len_s; ++i) { 26 | if(S[i] != T[i]) { 27 | return false; 28 | } 29 | } 30 | return true; 31 | // return len_s == len_t && S == T; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /matrix-exponentiation/b2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int mod = 1e9 + 7; 4 | #define REP(i, n) for(int i = 0; i < (n); i++) 5 | struct Matrix { 6 | long long a[2][2]; 7 | Matrix() { 8 | REP(i, 2) { 9 | REP(j, 2) { 10 | a[i][j] = 0; 11 | } 12 | } 13 | } 14 | Matrix operator *(Matrix other) { 15 | Matrix product = Matrix(); 16 | REP(i, 2) { 17 | REP(j, 2) { 18 | REP(k, 2) { 19 | product.a[i][k] += a[i][j] * other.a[j][k]; 20 | product.a[i][k] %= mod; 21 | } 22 | } 23 | } 24 | return product; 25 | } 26 | }; 27 | Matrix expo_power(Matrix a, long long n) { 28 | Matrix res = Matrix(); 29 | res.a[0][0] = res.a[1][1] = 1; 30 | while(n) { 31 | if(n % 2) { 32 | res = res * a; 33 | } 34 | n /= 2; 35 | a = a * a; 36 | } 37 | return res; 38 | } 39 | int main() { 40 | long long n; 41 | cin >> n; 42 | Matrix single = Matrix(); 43 | single.a[0][0] = 19; 44 | single.a[0][1] = 7; 45 | single.a[1][0] = 6; 46 | single.a[1][1] = 20; 47 | Matrix total = expo_power(single, n); 48 | cout << total.a[0][0] << endl; 49 | } 50 | -------------------------------------------------------------------------------- /AOC-2024/04.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int H = 140; 6 | vector a(H); 7 | for (string& row : a) { 8 | cin >> row; 9 | } 10 | int W = (int) a[0].length(); 11 | 12 | auto inside = [&](int row, int col) { 13 | return 0 <= row && row < H && 0 <= col && col < W; 14 | }; 15 | 16 | const string TEMP = "XMAS"; 17 | int answer = 0; 18 | for (int row = 0; row < H; row++) { 19 | for (int col = 0; col < W; col++) { 20 | if (a[row][col] == 'X') { 21 | for (int drow = -1; drow <= 1; drow++) { 22 | for (int dcol = -1; dcol <= 1; dcol++) { 23 | if (drow == 0 && dcol == 0) { 24 | continue; 25 | } 26 | bool all_ok = true; 27 | for (int i = 0; i < 4; i++) { 28 | int r2 = row + drow * i; 29 | int c2 = col + dcol * i; 30 | if (inside(r2, c2) && a[r2][c2] == TEMP[i]) { 31 | } 32 | else { 33 | all_ok = false; 34 | break; 35 | } 36 | } 37 | answer += all_ok; 38 | } 39 | } 40 | } 41 | } 42 | } 43 | cout << answer << "\n"; 44 | } 45 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/10-min-stack.cpp: -------------------------------------------------------------------------------- 1 | class MinStack { 2 | public: 3 | 4 | /*4, 6, 3, 2 5 | (4, 4) 6 | (6, 4) 7 | (3, 3) 8 | (2, 2)*/ 9 | 10 | stack> s; 11 | 12 | /** initialize your data structure here. */ 13 | MinStack() { 14 | //while(!s.empty()) { 15 | // s.clear(); 16 | 17 | } 18 | 19 | void push(int x) { 20 | if(s.empty()) { 21 | s.push({x, x}); 22 | } 23 | else { 24 | s.push({x, min(x, s.top().second)}); 25 | } 26 | } 27 | 28 | void pop() { 29 | if(!s.empty()) { 30 | s.pop(); 31 | } 32 | } 33 | 34 | int top() { 35 | return s.top().first; 36 | } 37 | 38 | int getMin() { 39 | return s.top().second; 40 | } 41 | }; 42 | 43 | /** 44 | * Your MinStack object will be instantiated and called as such: 45 | * MinStack* obj = new MinStack(); 46 | * obj->push(x); 47 | * obj->pop(); 48 | * int param_3 = obj->top(); 49 | * int param_4 = obj->getMin(); 50 | */ 51 | -------------------------------------------------------------------------------- /CSES/Introductory/15-creating-strings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int freq[26]; 5 | int n; 6 | vector answer; 7 | 8 | void build(string s) { // O(N! * (N+26)) 9 | if ((int) s.length() == n) { 10 | answer.push_back(s); 11 | return; 12 | } 13 | for (int i = 0; i < 26; i++) { 14 | if (freq[i] > 0) { 15 | freq[i]--; 16 | build(s + char('a'+i)); 17 | freq[i]++; 18 | } 19 | } 20 | } 21 | 22 | int main() { // O(N! * N) 23 | string s; 24 | cin >> s; 25 | n = (int) s.length(); 26 | for (char c : s) { 27 | freq[c-'a']++; 28 | } 29 | build(""); 30 | cout << answer.size() << "\n"; 31 | for (string a : answer) { 32 | cout << a << "\n"; 33 | } 34 | } 35 | 36 | /* 37 | #include 38 | using namespace std; 39 | 40 | int main() { // O(N! * N) 41 | string s; 42 | cin >> s; 43 | sort(s.begin(), s.end()); 44 | vector answer; 45 | do { 46 | answer.push_back(s); 47 | } while (next_permutation(s.begin(), s.end())); 48 | cout << answer.size() << "\n"; 49 | for (string a : answer) { 50 | cout << a << "\n"; 51 | } 52 | } 53 | */ 54 | -------------------------------------------------------------------------------- /rmq_sparse_table.cpp: -------------------------------------------------------------------------------- 1 | // video https://youtu.be/0jWeUdxrGm4 2 | // problem https://www.spoj.com/problems/RMQSQ/ 3 | #include 4 | using namespace std; 5 | 6 | const int MAX_N = 100'005; 7 | const int LOG = 17; 8 | int a[MAX_N]; 9 | int m[MAX_N][LOG]; // m[i][j] is minimum among a[i..i+2^j-1] 10 | int bin_log[MAX_N]; 11 | 12 | int query(int L, int R) { // O(1) 13 | int length = R - L + 1; 14 | int k = bin_log[length]; 15 | return min(m[L][k], m[R-(1<> n; 22 | bin_log[1] = 0; 23 | for(int i = 2; i <= n; i++) { 24 | bin_log[i] = bin_log[i/2]+1; 25 | } 26 | for(int i = 0; i < n; i++) { 27 | cin >> a[i]; 28 | m[i][0] = a[i]; 29 | } 30 | // 2) preprocessing, O(N*log(N)) 31 | for(int k = 1; k < LOG; k++) { 32 | for(int i = 0; i + (1 << k) - 1 < n; i++) { 33 | m[i][k] = min(m[i][k-1], m[i+(1<<(k-1))][k-1]); 34 | } 35 | } 36 | // 3) answer queries 37 | int q; 38 | cin >> q; 39 | for(int i = 0; i < q; i++) { 40 | int L, R; 41 | cin >> L >> R; 42 | cout << query(L, R) << "\n"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /AOC-2024/19.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | vector pats; 5 | 6 | char s[105]; 7 | while (true) { 8 | scanf("%s", s); 9 | char c; 10 | scanf("%c", &c); 11 | // printf("%s\n", s); 12 | 13 | pats.push_back(string(s)); 14 | if (pats.back().back() == ',') { 15 | pats.back().pop_back(); 16 | } 17 | // cout << pats.back() << "\n"; 18 | if (c != ' ') { 19 | break; 20 | } 21 | } 22 | int answer = 0; 23 | while (scanf("%s", s) != EOF) { 24 | // printf("%s\n", s); 25 | int L = strlen(s); 26 | vector dp(L+1); 27 | dp[0] = true; 28 | for (int i = 0; i < L; i++) { 29 | if (dp[i]) { 30 | for (string p : pats) { 31 | int k = p.length(); 32 | if (i + k <= L) { 33 | bool ok = true; 34 | for (int j = 0; j < k; j++) { 35 | if (s[i+j] != p[j]) { 36 | ok = false; 37 | break; 38 | } 39 | } 40 | if (ok) { 41 | dp[i+k] = true; 42 | } 43 | } 44 | } 45 | } 46 | } 47 | if (dp[L]) { 48 | answer++; 49 | } 50 | } 51 | printf("%d\n", answer); 52 | } 53 | -------------------------------------------------------------------------------- /POI/temperature/kd_ac.cpp: -------------------------------------------------------------------------------- 1 | // POI 18-2, Temperature 2 | // O(N), window maximum with deque-like structure 3 | #include 4 | using namespace std; 5 | int main() { 6 | int n; 7 | scanf("%d", &n); 8 | vector> in(n); 9 | for(pair& p : in) { 10 | scanf("%d%d", &p.first, &p.second); 11 | } 12 | 13 | vector indices{0}; // stack of indices of maxima 14 | int vector_start = 0; 15 | int answer = 1; // size 1 is always possible 16 | 17 | // Two pointers technique 18 | int a = 0; 19 | for(int b = 1; b < n; ++b) { 20 | while((int) indices.size() > vector_start && in[indices.back()].first < in[b].first) { 21 | indices.pop_back(); 22 | } 23 | indices.push_back(b); 24 | // we've just added in[b]. Maybe we must increase 'a' 25 | while(in[indices[vector_start]].first > in[b].second) { 26 | a = indices[vector_start] + 1; 27 | ++vector_start; 28 | } 29 | answer = max(answer, b - a + 1); // interval [a, b] is ok 30 | } 31 | printf("%d\n", answer); 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Errichto 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /AOC-2024/19-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | vector pats; 5 | 6 | char s[105]; 7 | while (true) { 8 | scanf("%s", s); 9 | char c; 10 | scanf("%c", &c); 11 | // printf("%s\n", s); 12 | 13 | pats.push_back(string(s)); 14 | if (pats.back().back() == ',') { 15 | pats.back().pop_back(); 16 | } 17 | // cout << pats.back() << "\n"; 18 | if (c != ' ') { 19 | break; 20 | } 21 | } 22 | long long answer = 0; 23 | while (scanf("%s", s) != EOF) { 24 | // printf("%s\n", s); 25 | int L = strlen(s); 26 | vector dp(L+1); 27 | dp[0] = 1; 28 | for (int i = 0; i < L; i++) { 29 | if (dp[i]) { 30 | for (string p : pats) { 31 | int k = p.length(); 32 | if (i + k <= L) { 33 | bool ok = true; 34 | for (int j = 0; j < k; j++) { 35 | if (s[i+j] != p[j]) { 36 | ok = false; 37 | break; 38 | } 39 | } 40 | if (ok) { 41 | dp[i+k] += dp[i]; 42 | } 43 | } 44 | } 45 | } 46 | } 47 | if (dp[L]) { 48 | answer += dp[L]; 49 | } 50 | } 51 | printf("%lld\n", answer); 52 | } 53 | -------------------------------------------------------------------------------- /CSES/Introductory/08-two-sets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // constructive problem 5 | 6 | int main() { 7 | int n; 8 | cin >> n; 9 | vector a, b; 10 | long long A = 0, B = 0; 11 | for (int x = n; x >= 1; --x) { 12 | if (A > B) { 13 | b.push_back(x); 14 | B += x; 15 | } 16 | else { 17 | a.push_back(x); 18 | A += x; 19 | } 20 | } 21 | if (A == B) { 22 | cout << "YES\n"; 23 | cout << a.size() << "\n"; 24 | for (int x : a) { 25 | cout << x << " "; 26 | } 27 | cout << "\n"; 28 | cout << b.size() << "\n"; 29 | for (int x : b) { 30 | cout << x << " "; 31 | } 32 | cout << "\n"; 33 | } 34 | else { 35 | cout << "NO\n"; 36 | } 37 | } 38 | 39 | // 1 2 3 4 5 6 7 SUM = even -> maybe we can split 40 | // SUM = odd -> cannot split 41 | // A: {7, 4, 3} 42 | // B: {6, 5, 2, 1} 43 | 44 | // N = 8 -> sum(1..8) = 8*9/2=36 45 | 46 | // A:{8,5,3,2} 47 | // B:{7,6,4,1} 48 | 49 | // invariant: after considering values n..x, the sum differs by at most x 50 | 51 | // A: n,n-3, n-4,n-7, ... 52 | // B: n-1,n-2,n-5,n-6, ... 53 | 54 | // homework: implement groups of 4 55 | -------------------------------------------------------------------------------- /AOC-2024/24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | map value; 5 | for (int i = 0; i < 90; i++) { 6 | char s[7]; 7 | scanf(" %s", s); 8 | int d; 9 | scanf(" %d", &d); 10 | value[string(s, s+3)] = d; 11 | } 12 | char a[5], op[5], b[5], c[5]; 13 | vector> ops; 14 | while (scanf(" %s", a) != EOF) { 15 | scanf(" %s %s -> %s", op, b, c); 16 | vector v{string(a), string(b), string(c), string(op)}; 17 | ops.push_back(v); 18 | } 19 | #define op ophello 20 | for (int rep = 0; rep < (int) ops.size(); rep++) { 21 | for (vector op : ops) { 22 | if (value.count(op[0]) && value.count(op[1]) && !value.count(op[2])) { 23 | int x = value[op[0]]; 24 | int y = value[op[1]]; 25 | string o = op[3]; 26 | value[op[2]] = (o == "XOR" ? x^y : (o == "OR" ? x|y : x&y)); 27 | } 28 | } 29 | } 30 | long long answer = 0; 31 | int i = 0; 32 | for (auto p : value) { 33 | if (p.first[0] == 'z') { 34 | answer += ((long long) p.second) << i; 35 | i++; 36 | // cout << p.first << " " << p.second << "\n"; 37 | } 38 | } 39 | printf("%lld\n", answer); 40 | } 41 | -------------------------------------------------------------------------------- /PSUT-coding-marathon/a.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | 35 | 36 | int main() { 37 | int n; 38 | cin >> n; 39 | int our = n / 3; 40 | cout << n - our << endl; 41 | } 42 | -------------------------------------------------------------------------------- /AOC-2024/10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | char a[505][505]; 5 | vector> dirs{{-1,0},{1,0},{0,-1},{0,1}}; 6 | int W, H; 7 | bool vis[505][505]; 8 | int dp[505][505]; 9 | 10 | bool inside(int row, int col) { 11 | return 0 <= row && row < H && 0 <= col && col < W; 12 | } 13 | 14 | // O(H*W) 15 | 16 | int dfs(int row, int col) { 17 | if (vis[row][col]) { 18 | return dp[row][col]; 19 | } 20 | vis[row][col] = true; 21 | if (a[row][col] == '9') { 22 | return dp[row][col] = 1; 23 | } 24 | int total = 0; 25 | for (pair dir : dirs) { 26 | int r2 = row + dir.first; 27 | int c2 = col + dir.second; 28 | if (inside(r2, c2) && a[r2][c2] == a[row][col]+1) { 29 | total += dfs(r2, c2); 30 | } 31 | } 32 | return dp[row][col] = total; 33 | } 34 | 35 | int main() { 36 | for (int row = 0; scanf("%s", a[row]) != EOF; row++) { 37 | H = row + 1; 38 | W = strlen(a[row]); 39 | } 40 | int answer = 0; 41 | for (int row = 0; row < H; row++) { 42 | for (int col = 0; col < W; col++) { 43 | if (a[row][col] == '0') { 44 | answer += dfs(row, col); 45 | } 46 | } 47 | } 48 | cout << answer << "\n"; 49 | } 50 | -------------------------------------------------------------------------------- /isolation/brute.cpp: -------------------------------------------------------------------------------- 1 | // O(N^2) 2 | #include 3 | using namespace std; 4 | 5 | const int mod = 998244353; 6 | const int MAX_N = 1e5 + 5; // 100,005 7 | vector occurrences[MAX_N]; 8 | int cnt[MAX_N], dp[MAX_N]; 9 | 10 | void add(int a, int b, int diff) { 11 | for(int i = a; i <= b; ++i) { 12 | cnt[i] += diff; 13 | } 14 | } 15 | 16 | int main() { 17 | int n, k; 18 | scanf("%d%d", &n, &k); 19 | for(int x = 1; x <= n; ++x) { 20 | occurrences[x].push_back(-1); // fake position 21 | } 22 | dp[0] = 1; 23 | for(int R = 0; R < n; ++R) { 24 | int x; 25 | scanf("%d", &x); 26 | vector& vec = occurrences[x]; 27 | if((int) vec.size() >= 2) { 28 | add(vec.end()[-2] + 1, vec.back(), -1); 29 | } 30 | add(vec.back() + 1, R, 1); 31 | vec.push_back(R); 32 | for(int L = 0; L <= R; ++L) { 33 | if(cnt[L] <= k) { 34 | dp[R+1] += dp[L]; 35 | if(dp[R+1] >= mod) { 36 | dp[R+1] -= mod; 37 | } 38 | } 39 | } 40 | } 41 | printf("%d\n", dp[n]); 42 | } 43 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/19-search-in-rotated-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int search(vector& nums, int target) { 4 | int n = nums.size(); 5 | if(n == 0) { 6 | return -1; 7 | } 8 | int low = 0, high = n - 1; 9 | int first = nums[0]; 10 | while(low <= high) { 11 | int mid = low + (high - low) / 2; 12 | int value = nums[mid]; 13 | if(value == target) { 14 | return mid; 15 | } 16 | bool am_big = value >= first; 17 | bool target_big = target >= first; 18 | if(am_big == target_big) { 19 | if(value < target) { 20 | low = mid + 1; 21 | } 22 | else { 23 | high = mid - 1; 24 | } 25 | } 26 | else { 27 | if(am_big) { 28 | low = mid + 1; 29 | } 30 | else { 31 | high = mid - 1; 32 | } 33 | } 34 | } 35 | return -1; 36 | } 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /leetcode/1223-dice.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/dice-roll-simulation/ 2 | class Solution { 3 | const int mod = 1e9 + 7; 4 | void add_self(int& a, int b) { 5 | a = (a + b) % mod; 6 | } 7 | public: 8 | int dieSimulator(int n, 9 | vector& rollMax) { 10 | vector> ways(n + 1, vector(6)); 11 | for(int a = 0; a < 6; ++a) { 12 | for(int len = 1; len <= min(n, rollMax[a]); ++len) { 13 | ways[len][a]++; 14 | } 15 | } 16 | // O(n * rollMax * poly(6)) 17 | for(int i = 1; i <= n; ++i) { 18 | for(int prv = 0; prv < 6; ++prv) { 19 | for(int nxt = 0; nxt < 6; ++nxt) { 20 | if(prv == nxt) { 21 | continue; 22 | } 23 | for(int len = 1; len <= rollMax[nxt] && i - len >= 0; ++len) { 24 | add_self(ways[i][nxt], ways[i-len][prv]); 25 | } 26 | } 27 | } 28 | } 29 | int answer = 0; 30 | for(int a = 0; a < 6; a++) { 31 | add_self(answer, ways[n][a]); 32 | } 33 | return answer; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /leetcode/1483-kth-ancestor.cpp: -------------------------------------------------------------------------------- 1 | // Binary Lifting tutorial https://youtu.be/oib-XsjFa-M 2 | class TreeAncestor { 3 | vector> up; // int up[N][20]; 4 | vector depth; 5 | int LOG; 6 | public: 7 | TreeAncestor(int n, vector& parent) { 8 | LOG = 0; 9 | while((1 << LOG) <= n) { 10 | LOG++; 11 | } 12 | up = vector>(n, vector(LOG)); 13 | depth = vector(n); 14 | // up[v][j] is 2^j -th ancestor of node v 15 | parent[0] = 0; 16 | for(int v = 0; v < n; v++) { 17 | up[v][0] = parent[v]; 18 | if(v != 0) { 19 | depth[v] = depth[parent[v]] + 1; 20 | } 21 | for(int j = 1; j < LOG; j++) { 22 | up[v][j] = up[ up[v][j-1] ][j-1]; 23 | } 24 | } 25 | } 26 | int getKthAncestor(int node, int k) { 27 | if(depth[node] < k) { 28 | return -1; 29 | } 30 | for(int j = LOG - 1; j >= 0; j--) { 31 | if(k >= (1 << j)) { 32 | node = up[node][j]; 33 | k -= 1 << j; 34 | } 35 | } 36 | return node; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /leetcode/1222-queens.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/queens-that-can-attack-the-king/ 2 | class Solution { 3 | bool inside(int row, int col) { 4 | return 0 <= row && row < 8 5 | && 0 <= col && col < 8; 6 | } 7 | public: 8 | vector> queensAttacktheKing( 9 | vector>& queens, 10 | vector& king 11 | ) { 12 | vector> taken(8, vector(8)); 13 | for(vector queen : queens) { 14 | taken[queen[0]][queen[1]] = true; 15 | } 16 | vector> answer; 17 | for(int d1 = -1; d1 <= 1; d1++) { 18 | for(int d2 = -1; d2 <= 1; d2++) { 19 | if(d1 == 0 && d2 == 0) { 20 | continue; 21 | } 22 | int row = king[0]; 23 | int col = king[1]; 24 | do { 25 | row += d1; 26 | col += d2; 27 | } while(inside(row, col) && !taken[row][col]); 28 | if(inside(row, col)) { 29 | answer.push_back({row, col}); 30 | } 31 | } 32 | } 33 | return answer; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/13-contiguous-array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findMaxLength(self, nums: List[int]) -> int: 3 | first_oc = {} 4 | first_oc[0] = 0 5 | answer = 0 6 | pref = 0 7 | n = len(nums) 8 | for i in range(n): 9 | pref += (1 if nums[i] == 1 else -1) 10 | if pref in first_oc: 11 | answer = max(answer, i + 1 - first_oc[pref]) 12 | else: 13 | first_oc[pref] = i + 1 14 | return answer 15 | 16 | 17 | """class Solution { 18 | public: 19 | int findMaxLength(vector& nums) { 20 | unordered_map first_oc; 21 | first_oc[0] = 0; 22 | int answer = 0; 23 | int pref = 0; 24 | for(int i = 0; i < (int) nums.size(); ++i) { 25 | pref += (nums[i] == 0 ? -1 : 1); 26 | auto it = first_oc.find(pref); 27 | if(it != first_oc.end()) { // exists 28 | answer = max(answer, i + 1 - first_oc[pref]); 29 | } 30 | else { 31 | first_oc[pref] = i + 1; 32 | } 33 | } 34 | return answer; 35 | // O(N) space and time 36 | } 37 | };""" 38 | -------------------------------------------------------------------------------- /GCJ/2021/1C/closest_pick.cpp: -------------------------------------------------------------------------------- 1 | // Closest Pick 2 | // https://codingcompetitions.withgoogle.com/codejam/round/00000000004362d7/00000000007c0f00 3 | #include 4 | using namespace std; 5 | 6 | void test_case() { 7 | int n, k; 8 | scanf("%d%d", &n, &k); 9 | vector a(n); 10 | for(int i = 0; i < n; i++) { 11 | scanf("%d", &a[i]); 12 | } 13 | sort(a.begin(), a.end()); 14 | int answer = 0; 15 | vector best; 16 | best.push_back(a[0] - 1); 17 | best.push_back(k - a.back()); 18 | for(int i = 0; i < (int) a.size() - 1; i++) { 19 | int x = a[i]; 20 | int y = a[i+1]; 21 | answer = max(answer, y - x - 1); 22 | best.push_back((y - x) / 2); 23 | } 24 | sort(best.rbegin(), best.rend()); 25 | answer = max(answer, best[0] + best[1]); 26 | printf("%.10lf\n", (double) answer / k); 27 | } 28 | 29 | int main() { 30 | int T; 31 | scanf("%d", &T); 32 | for(int x = 1; x <= T; x++) { 33 | printf("Case #%d: ", x); 34 | test_case(); 35 | } 36 | } 37 | 38 | /* 39 | 40 | 1 3 7 41 | 6 8 42 | 43 | 44 | 45 | 46 | 47 | 10 14 48 | 13 -> 2 49 | 50 | 10 15 51 | 14 -> 2 52 | 53 | 54 | A B -> (B - A) / 2*/ 55 | -------------------------------------------------------------------------------- /matrix-exponentiation/d2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n; 4 | const int mod = 1e9 + 7; 5 | struct Matrix { 6 | vector> a = vector>(n, vector(n)); 7 | void operator *=(const Matrix& other) { 8 | vector> product(n, vector(n)); 9 | for(int i = 0; i < n; ++i) { 10 | for(int j = 0; j < n; ++j) { 11 | for(int k = 0; k < n; ++k) { 12 | product[i][k] = (product[i][k] + (long long) a[i][j] * other.a[j][k]) % mod; 13 | } 14 | } 15 | } 16 | a = product; 17 | } 18 | }; 19 | Matrix expo_power(Matrix a, int k) { 20 | Matrix res; 21 | for(int i = 0; i < n; ++i) { 22 | res.a[i][i] = 1; 23 | } 24 | while(k) { 25 | if(k % 2) { 26 | res *= a; 27 | } 28 | k /= 2; 29 | a *= a; 30 | } 31 | return res; 32 | } 33 | int main() { 34 | int m, k; 35 | scanf("%d%d%d", &n, &m, &k); 36 | Matrix base; 37 | for(int i = 0; i < m; ++i) { 38 | int a, b; 39 | scanf("%d%d", &a, &b); 40 | base.a[a-1][b-1]++; 41 | } 42 | Matrix total = expo_power(base, k); 43 | int answer = 0; 44 | for(int i = 0; i < n; ++i) { 45 | for(int j = 0; j < n; ++j) { 46 | answer = (answer + total.a[i][j]) % mod; 47 | } 48 | } 49 | printf("%d\n", answer); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /leetcode/1345-jump-game-iv.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/jump-game-iv/ 2 | class Solution { 3 | public: 4 | int minJumps(vector& a) { 5 | int n = a.size(); 6 | vector visited(n); 7 | visited[0] = true; 8 | vector> q; 9 | q.emplace_back(0, 0); 10 | map> occurrences; 11 | for(int i = 0; i < n; ++i) { 12 | occurrences[a[i]].push_back(i); 13 | } 14 | for(int iq = 0; iq < (int) q.size(); iq++) { 15 | int i = q[iq].first; 16 | int dist = q[iq].second; 17 | if(i == n - 1) { 18 | return dist; 19 | } 20 | for(int j : {i - 1, i + 1}) { 21 | if(0 <= j && j < n && !visited[j]) { 22 | visited[j] = true; 23 | q.emplace_back(j, dist + 1); 24 | } 25 | } 26 | for(int j : occurrences[a[i]]) { 27 | if(!visited[j]) { 28 | visited[j] = true; 29 | q.emplace_back(j, dist + 1); 30 | } 31 | } 32 | occurrences[a[i]].clear(); 33 | } 34 | assert(false); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /AOC-2024/03-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | string s; 6 | char c; 7 | while (scanf("%c", &c) != EOF) { 8 | s += c; 9 | } 10 | s += "#####################"; 11 | 12 | int n = (int) s.length(); 13 | 14 | auto getNumber = [&](int& i) { 15 | int x = 0; 16 | while (x < 1000 && isdigit(s[i])) { 17 | x = 10 * x + (s[i] - '0'); 18 | i++; 19 | } 20 | if (1 <= x && x <= 999) { 21 | return x; 22 | } 23 | return -1; 24 | }; 25 | 26 | bool enable = true; 27 | int answer = 0; 28 | for (int i = 0; i < n - 7; i++) { 29 | if (s.substr(i, 4) == "do()") { 30 | // cout << "do\n"; 31 | enable = true; 32 | } 33 | if (s.substr(i, 7) == "don\'t()") { 34 | // cout << "do not\n"; 35 | enable = false; 36 | } 37 | if (enable && s[i] == 'm') { 38 | if (s[i+1] == 'u' && s[i+2] == 'l' && s[i+3] == '(') { 39 | i += 4; 40 | int x = getNumber(i); 41 | // cout << i << " " << x << endl; 42 | if (s[i] == ',') { 43 | i += 1; 44 | int y = getNumber(i); 45 | // cout << ">> " << i << " " << x << " " << y << endl; 46 | if (s[i] == ')') { 47 | if (x != -1 && y != -1) { 48 | answer += x * y; 49 | } 50 | } 51 | } 52 | } 53 | } 54 | } 55 | printf("%d\n", answer); 56 | } 57 | -------------------------------------------------------------------------------- /matrix-exponentiation/f2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using ll = long long; 4 | const ll INF = 2e18L + 5; 5 | int n; 6 | #define REP(i) for(int i = 0; i < n; i++) 7 | struct Matrix { 8 | vector> a = vector>(n, vector(n, INF)); 9 | Matrix operator *(Matrix other) { 10 | Matrix product; 11 | REP(i) { 12 | REP(j) { 13 | REP(k) { 14 | product.a[i][k] = min(product.a[i][k], a[i][j] + other.a[j][k]); 15 | } 16 | } 17 | } 18 | return product; 19 | } 20 | }; 21 | Matrix expo_power(Matrix a, long long k) { 22 | Matrix res = Matrix(); 23 | for(int i = 0; i < n; ++i) { 24 | res.a[i][i] = 0; 25 | } 26 | while(k) { 27 | if(k % 2) { 28 | res = res * a; 29 | } 30 | k /= 2; 31 | a = a * a; 32 | } 33 | return res; 34 | } 35 | int main() { 36 | int m, k; 37 | scanf("%d%d%d", &n, &m, &k); 38 | Matrix single; 39 | while(m--) { 40 | int a, b, c; 41 | scanf("%d%d%d", &a, &b, &c); 42 | single.a[a-1][b-1] = c; 43 | } 44 | Matrix total = expo_power(single, k); 45 | ll answer = INF; 46 | for(int i = 0; i < n; ++i) { 47 | for(int j = 0; j < n; ++j) { 48 | answer = min(answer, total.a[i][j]); 49 | } 50 | } 51 | if(answer > INF / 2) { 52 | puts("IMPOSSIBLE"); 53 | } 54 | else { 55 | printf("%lld\n", answer); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/07-counting-elements.cpp: -------------------------------------------------------------------------------- 1 | count elements x such that there exists some other element different by at most K 2 | K=4 3 | 4 | 5 8 8 8 8 8 8 13 14 14 ... 5 | ^ 6 | 7 | class Solution { 8 | public: 9 | int countElements(vector& arr, int K) { 10 | int n = arr.size(); 11 | sort(arr.begin(), arr.end()); 12 | int prv = -INF, prv_cnt = 0; 13 | int before_me_value = -INF; 14 | for(int i = 0; i < n; ++i) { 15 | if(i == n - 1 || arr[i] != arr[i+1]) { 16 | if((i!=n-1 && arr[i+1] <= arr[i] + K) || before_me_value >= arr[i]-K) { 17 | answer += prv_cnt; 18 | } 19 | } 20 | if(arr[i] == prv) { 21 | prv_cnt++; 22 | } 23 | else { 24 | before_me_value = prv; 25 | prv = arr[i]; 26 | prv_cnt = 1; 27 | } 28 | } 29 | return answer; 30 | 31 | /* unordered_set s; 32 | for(int x : arr) { 33 | s.insert(x); 34 | } 35 | int cnt = 0; 36 | for(int x : arr) { 37 | if(s.count(x+1) == 1) { 38 | cnt++; 39 | } 40 | } 41 | return cnt; 42 | */ 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /codeforces/614a-maze-game.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n, q; 6 | scanf("%d%d", &n, &q); 7 | set> cells; // O(log) per operation 8 | int bad_nei = 0; 9 | for(int i = 0; i < q; i++) { 10 | int row, col; 11 | scanf("%d%d", &row, &col); 12 | bool was_forbidden = cells.count({row, col}); 13 | for(int r = row - 1; r <= row + 1; r++) { 14 | for(int c = col - 1; c <= col + 1; c++) { 15 | if(r == row) { 16 | continue; 17 | } 18 | if(!(1 <= r && r <= 2 && 1 <= c && c <= n)) { 19 | continue; 20 | } 21 | if(cells.count({r, c})) { 22 | if(was_forbidden) { 23 | bad_nei--; 24 | } 25 | else { 26 | bad_nei++; 27 | } 28 | } 29 | } 30 | } 31 | if(cells.count({row, col})) { 32 | cells.erase({row, col}); 33 | } 34 | else { 35 | cells.insert({row, col}); 36 | } 37 | if(bad_nei >= 1) { 38 | puts("NO"); 39 | } 40 | else { 41 | puts("YES"); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/25-jump-game.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool canJump(vector& nums) { 4 | // minimize the number of jumps 5 | if(n <= 1) { 6 | cout << 0 << endl; 7 | return true; // 0 jumps 8 | } 9 | pair interval{0, 0}; 10 | int jumps = 0; 11 | while(true) { 12 | jumps++; 13 | int can_reach = -1; 14 | for(int i = interval.first; i <= interval.second; ++i) { 15 | can_reach = max(can_reach, i + nums[i]); 16 | } 17 | if(can_reach >= n - 1) { 18 | cout << jumps << endl; 19 | return true; // jumps 20 | } 21 | interval = {interval.second+1, can_reach}; 22 | //cout << interval.first << " " << interval.second << endl; 23 | if(interval.first > interval.second) { 24 | return false; 25 | } 26 | } 27 | assert(false); 28 | /* 29 | int n = nums.size(); 30 | int can_reach = 0; 31 | for(int i = 0; i <= can_reach; ++i) { 32 | if(i == n - 1) { 33 | return true; 34 | } 35 | can_reach = max(can_reach, i + nums[i]); 36 | } 37 | return false; 38 | */ 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /AOC-2024/11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // bool isOdd(long long x) { 5 | // return to_string(x).length() % 2 == 1; 6 | // } 7 | 8 | int main() { 9 | // INPUT * 2024 * 2024 10 | 11 | // for (long long x = 1; x <= 100'000'000; x++) { 12 | 13 | // if (isOdd(x) && isOdd(x * 2024) && isOdd(x * 2024 * 2024)) { 14 | // cout << x << " "; 15 | // } 16 | // } 17 | // cout << "NONE"; 18 | // return 0; 19 | 20 | 21 | map v; 22 | int tmp; 23 | while (scanf("%d", &tmp) != EOF) { 24 | v[tmp]++; 25 | } 26 | for (int rep = 0; rep < 1000; rep++) { 27 | map newV; 28 | for (auto [x,cnt] : v) { 29 | if (x == 0) { 30 | newV[1] += cnt; 31 | } 32 | else if (to_string(x).length() % 2 == 0) { 33 | string s = to_string(x); 34 | int k = s.length(); 35 | newV[stoll(s.substr(0, k/2))] += cnt; 36 | newV[stoll(s.substr(k/2, k/2))] += cnt; 37 | } 38 | else { 39 | newV[x * 2024] += cnt; 40 | } 41 | } 42 | v = newV; 43 | // cout << rep << " " << v.size() << " " << *max_element(v.begin(), v.end()) << "\n"; 44 | } 45 | // for (long long x : v) { 46 | // cout << x << " "; 47 | // } 48 | 49 | long long total = 0; 50 | for (auto pp : v) { 51 | total += pp.second; 52 | } 53 | printf("%lld\n", total); 54 | cerr << v.size() << "\n"; 55 | } 56 | -------------------------------------------------------------------------------- /AOC-2024/22-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int MOD = 1 << 24; 5 | void f(long long& x) { 6 | x ^= x * 64; 7 | x %= MOD; 8 | x ^= x / 32; 9 | x %= MOD; 10 | x ^= x * 2048LL; 11 | x %= MOD; 12 | } 13 | 14 | int vis[21][21][21][21]; 15 | int m[21][21][21][21]; 16 | // map, int> m; 17 | 18 | int main() { 19 | long long x; 20 | int id = 0; 21 | while (scanf("%lld", &x) != EOF) { 22 | id++; 23 | vector v; 24 | int n = 2000; 25 | v.push_back(x % 10); 26 | // set> s; 27 | for (int i = 1; i <= n; i++) { 28 | f(x); 29 | v.push_back(x % 10); 30 | if (i >= 4) { 31 | int d[4]; 32 | for (int j = 0; j < 4; j++) { 33 | d[j] = v[i-4+1+j] - v[i-4+j]; 34 | } 35 | if (vis[d[0]+10][d[1]+10][d[2]+10][d[3]+10] != id) { 36 | vis[d[0]+10][d[1]+10][d[2]+10][d[3]+10] = id; 37 | m[d[0]+10][d[1]+10][d[2]+10][d[3]+10] += x % 10; 38 | // m[d] += x % 10; 39 | } 40 | } 41 | } 42 | } 43 | int answer = 0; 44 | for (int i = 0; i <= 20; i++) { 45 | for (int j = 0; j <= 20; j++) { 46 | for (int k = 0; k <= 20; k++) { 47 | for (int l = 0; l <= 20; l++) { 48 | answer = max(answer, m[i][j][k][l]); 49 | } 50 | } 51 | } 52 | } 53 | // for (auto p : m) { 54 | // answer = max(answer, p.second); 55 | // } 56 | printf("%d\n", answer); 57 | } 58 | -------------------------------------------------------------------------------- /AOC-2024/23-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | map> edges; // adjacency list 4 | set vis; 5 | set> pairs; // set of edges 6 | vector big; 7 | 8 | void rec(string a, int i, vector clique) { 9 | if (i == (int) edges[a].size()) { 10 | if (clique.size() > big.size()) { 11 | big = clique; 12 | } 13 | // if ((int) clique.size() == 13) cout << "X"; 14 | // cout << clique.size() << " "; 15 | return; 16 | } 17 | 18 | rec(a, i + 1, clique); 19 | 20 | string b = edges[a][i]; 21 | for (string s : clique) { 22 | if (!pairs.count({b,s})) { 23 | return; 24 | } 25 | } 26 | clique.push_back(b); 27 | rec(a, i + 1, clique); 28 | } 29 | 30 | int main() { 31 | char s[7]; 32 | set nodes; 33 | // not using: adjacency matrix 34 | while (scanf("%s", s) != EOF) { 35 | // printf("> %s\n", s); 36 | string a(s, s + 2); 37 | string b(s + 3, s + 5); 38 | 39 | nodes.insert(a); 40 | nodes.insert(b); 41 | edges[a].push_back(b); 42 | edges[b].push_back(a); 43 | pairs.insert({a,b}); 44 | pairs.insert({b,a}); 45 | } 46 | 47 | for (string a : nodes) { 48 | rec(a, 0, {a}); 49 | } 50 | 51 | // cout << big.size() << "\n"; 52 | sort(big.begin(), big.end()); 53 | for (string s : big) { 54 | cout << s << ","; 55 | } 56 | cout << "\n"; 57 | } 58 | -------------------------------------------------------------------------------- /AOC-2024/09.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct Block { 5 | int id, size, pos; 6 | }; 7 | 8 | int main() { 9 | string s; 10 | cin >> s; 11 | int n = s.length(); 12 | int pos = 0; 13 | vector blocks; 14 | for (int i = 0; i < n; i++) { 15 | int digit = s[i] - '0'; 16 | if (i % 2 == 0) { 17 | for (int rep = 0; rep < digit; rep++) { 18 | blocks.push_back(Block{i/2, 1, pos + rep}); 19 | } 20 | } 21 | pos += digit; 22 | } 23 | // for (Block block : blocks) { 24 | // cout << block.pos << " " << block.id << " " << block.size << "\n"; 25 | // } 26 | // return 0; 27 | while (true) { 28 | Block me = blocks.back(); 29 | blocks.pop_back(); 30 | bool inserted = false; 31 | for (int i = 0; i < (int) blocks.size() - 1; i++) { 32 | int A = blocks[i].pos + blocks[i].size; 33 | int B = blocks[i+1].pos; 34 | if (B - A >= me.size) { 35 | inserted = true; 36 | me.pos = A; 37 | blocks.insert(blocks.begin() + i + 1, me); 38 | break; 39 | } 40 | } 41 | if (!inserted) { 42 | me.pos = blocks.back().pos + blocks.back().size; 43 | blocks.push_back(me); 44 | break; 45 | } 46 | } 47 | long long answer = 0; 48 | for (Block block : blocks) { 49 | // cout << block.pos << " " << block.id << "\n"; 50 | answer += (long long) block.pos * block.id; 51 | } 52 | cout << answer << "\n"; 53 | } 54 | -------------------------------------------------------------------------------- /painting-the-fence/solution2.cpp: -------------------------------------------------------------------------------- 1 | // O(n*q*skipped) 2 | #include "bits/stdc++.h" 3 | using namespace std; 4 | const int INF = 1e9 + 5; 5 | void max_self(int& a, int b) { 6 | a = max(a, b); 7 | } 8 | 9 | int main() { 10 | int n, q; 11 | scanf("%d%d", &n, &q); 12 | vector> intervals(q); 13 | for(pair& p : intervals) { 14 | scanf("%d%d", &p.first, &p.second); 15 | --p.first; 16 | --p.second; 17 | } 18 | sort(intervals.begin(), intervals.end()); 19 | vector> dp(n + 1, vector(3, -INF)); 20 | // dp[x][y] - max number of covered cells if 21 | // the next cell to paint is 'x' and we skipped 'y' painters so far 22 | dp[0][0] = 0; 23 | for(pair p : intervals) { 24 | for(int x = n; x >= 0; --x) { 25 | int extra = max(0, p.second - max(x, p.first) + 1); 26 | for(int skipped = 2; skipped >= 0; --skipped) { 27 | if(skipped != 2) { 28 | max_self(dp[x][skipped+1], dp[x][skipped]); 29 | } 30 | max_self(dp[max(x, p.second + 1)][skipped], dp[x][skipped] + extra); 31 | } 32 | } 33 | } 34 | int answer = 0; 35 | for(int i = 0; i <= n; ++i) { 36 | answer = max(answer, dp[i][2]); // 2 painters must be skipped 37 | } 38 | printf("%d\n", answer); 39 | } 40 | -------------------------------------------------------------------------------- /CSES/Introductory/21-grid-coloring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int H, W; // height, width 6 | cin >> H >> W; 7 | vector a(H); 8 | for (string& row : a) { 9 | cin >> row; 10 | } 11 | // O(H*W) 12 | for (int row = 0; row < H; row++) { 13 | for (int col = 0; col < W; col++) { 14 | if ((row + col) % 2 == 0) { 15 | a[row][col] = (a[row][col] == 'A' ? 'C' : 'A'); 16 | } 17 | else { 18 | a[row][col] = (a[row][col] == 'B' ? 'D' : 'B'); 19 | } 20 | // set s; 21 | // if (row != 0) { 22 | // s.insert(a[row-1][col]); 23 | // } 24 | // if (col != 0) { 25 | // s.insert(a[row][col-1]); 26 | // } 27 | // s.insert(a[row][col]); 28 | // for (char x = 'A'; x <= 'D'; x++) { 29 | // if (!s.count(x)) { 30 | // a[row][col] = x; 31 | // break; 32 | // } 33 | // } 34 | } 35 | cout << a[row] << "\n"; 36 | } 37 | } 38 | 39 | // ...... 40 | // ..A... 41 | // .B?... 42 | // ...... 43 | 44 | // originally = C 45 | 46 | 47 | // CDABAB 48 | // BABABA 49 | // ABABAB 50 | 51 | 52 | // ........... 53 | // ....A...... 54 | // ...B?...... 55 | // ........... 56 | // ........... 57 | // ........... 58 | // .....A..... 59 | // ....B?D.... 60 | // .....C..... 61 | // ........... 62 | // ........... 63 | 64 | // If we chose random order of filling H*W cells, 65 | // we could fail 66 | -------------------------------------------------------------------------------- /AOC-2024/05.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | string s; 6 | map> edges; 7 | long long answer = 0; 8 | while (getline(cin, s)) { 9 | if (s.empty() || !isdigit(s[0])) { 10 | continue; 11 | } 12 | int len = (int) s.length(); 13 | // cout << s << "\n"; 14 | vector v; 15 | bool was_pipe = false; 16 | for (int i = 0; i < len; i++) { 17 | if (isdigit(s[i])) { 18 | int x = 0; 19 | while (isdigit(s[i])) { 20 | x = 10 * x + (s[i] - '0'); 21 | i++; 22 | } 23 | v.push_back(x); 24 | // cout << "i=" << i << " s[i]=" << int(s[i]) << "\n"; 25 | if (s[i] == '|') { 26 | was_pipe = true; 27 | } 28 | assert(s[i] == ',' || s[i] == '|' || s[i] == '\n' || s[i] == 0); 29 | // cout << "x=" << x << " "; 30 | } 31 | } 32 | if (was_pipe) { 33 | edges[v[0]].push_back(v[1]); 34 | } 35 | else { 36 | set earlier; 37 | bool ok = true; 38 | // O(Q * K * OUT_DEGREE * log) 39 | // O(Q * K^2 * log) -- if you iterated pairs (x,y) in the input 40 | for (int i = 0; i < (int) v.size(); i++) { 41 | int x = v[i]; 42 | for (int y : edges[x]) { 43 | if (earlier.count(y)) { 44 | ok = false; 45 | } 46 | } 47 | earlier.insert(x); 48 | } 49 | if (ok) { 50 | answer += v[v.size()/2]; 51 | } 52 | } 53 | } 54 | cout << answer << "\n"; 55 | } 56 | -------------------------------------------------------------------------------- /matrix-exponentiation/d.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define REP(i,n) for(int i = 0; i < (n); i++) 4 | const int mod = 1e9 + 7; 5 | int n; 6 | struct Matrix { 7 | vector> a = vector>(n, vector(n)); 8 | Matrix operator *(const Matrix& other) { 9 | Matrix product; 10 | vector> tmp(n, vector(n)); 11 | REP(i,n)REP(j,n)REP(k,n) { 12 | tmp[i][k] += (long long) a[i][j] * other.a[j][k]; 13 | if(tmp[i][k] >= 8LL * mod * mod) { 14 | tmp[i][k] %= mod; 15 | } 16 | // product.a[i][k] = (product.a[i][k] + (long long) a[i][j] * other.a[j][k]) % mod; 17 | } 18 | REP(i,n)REP(j,n) product.a[i][j] = tmp[i][j] % mod; 19 | return product; 20 | } 21 | }; 22 | Matrix expo_power(Matrix a, long long k) { 23 | Matrix product; 24 | REP(i,n) product.a[i][i] = 1; 25 | while(k > 0) { 26 | if(k % 2) { 27 | product = product * a; 28 | } 29 | a = a * a; 30 | k /= 2; 31 | } 32 | return product; 33 | } 34 | int main() { 35 | // D. Count Paths 36 | int m; 37 | long long k; 38 | cin >> n >> m >> k; 39 | Matrix single; 40 | for(int i = 0; i < m; i++) { 41 | int u, v; 42 | cin >> u >> v; 43 | single.a[u-1][v-1] = 1; 44 | } 45 | Matrix total = expo_power(single, k); 46 | int answer = 0; 47 | REP(i, n) REP(j, n) { 48 | answer = (answer + total.a[i][j]) % mod; 49 | } 50 | cout << answer << endl; 51 | } 52 | -------------------------------------------------------------------------------- /AOC-2024/25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int arr[7][7][7][7][7]; 5 | 6 | void prefSums() { 7 | // 2D pref sums 8 | // SOS (sum over subset) 9 | for (int w = 0; w < 5; w++) { 10 | for (int a = 0; a < 6; a++) { 11 | for (int b = 0; b < 6; b++) { 12 | for (int c = 0; c < 6; c++) { 13 | for (int d = 0; d < 6; d++) { 14 | for (int e = 0; e < 6; e++) { 15 | arr[a+(w==0)][b+(w==1)][c+(w==2)][d+(w==3)][e+(w==4)] += arr[a][b][c][d][e]; 16 | } 17 | } 18 | } 19 | } 20 | } 21 | } 22 | } 23 | 24 | // O(OBJECTS + 6**5) 25 | 26 | int main() { 27 | vector> A; 28 | char s[10]; 29 | while (scanf(" %s", s) != EOF) { 30 | vector grid; 31 | grid.push_back(string(s)); 32 | for (int i = 0; i < 6; i++) { 33 | scanf(" %s", s); 34 | grid.push_back(string(s)); 35 | } 36 | vector v; 37 | for (int col = 0; col < 5; col++) { 38 | int cnt = 0; 39 | for (int row = 0; row < 7; row++) { 40 | if (grid[row][col] == '#') { 41 | cnt++; 42 | } 43 | } 44 | v.push_back(cnt - 1); 45 | } 46 | if (grid[0][0] == '#') { 47 | A.push_back(v); 48 | } 49 | else { 50 | arr[v[0]][v[1]][v[2]][v[3]][v[4]]++; 51 | } 52 | } 53 | prefSums(); 54 | int answer = 0; 55 | for (vector v : A) { 56 | answer += arr[5-v[0]][5-v[1]][5-v[2]][5-v[3]][5-v[4]]; 57 | } 58 | printf("%d\n", answer); 59 | } 60 | -------------------------------------------------------------------------------- /lectures/binary-search/search-in-rotated-sorted-array.py: -------------------------------------------------------------------------------- 1 | # Search in Rotated Sorted Array, https://leetcode.com/explore/learn/card/binary-search/125/template-i/952/ 2 | # This is the harder of two rotated-array problems in Leetcode. 3 | 4 | # There are two options: 5 | # 1) First find the rotation (the position of the smallest element) and then find the target value in one of the parts. This approach requires one binary search and then another different binary search. 6 | # 2) Run one binary search with more complicated if-conditions to look for the number - this is what my code does. You should try yourself the first approach. 7 | 8 | class Solution: 9 | def search(self, a: List[int], target: int) -> int: 10 | # For each number we can check if we should go to the left/right by comparing it with target and with a[0]. Also, comparing target with a[0] tells us in which part (big or small numbers) the target is. 11 | n = len(a) 12 | left, right = 0, n - 1 13 | while left <= right: 14 | mid = left + (right - left) // 2 15 | if a[mid] == target: 16 | return mid # no need to store the answer, just return it 17 | if (target >= a[0] and (a[mid] >= target or a[mid] < a[0])) or (target < a[0] and (a[mid] < a[0] and a[mid] >= target)): 18 | right = mid - 1 19 | else: 20 | left = mid + 1 21 | return -1 22 | -------------------------------------------------------------------------------- /matrix-exponentiation/i.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n; 4 | const int mod = 1e9 + 7; 5 | struct Matrix { 6 | vector> a = vector>(n, vector(n)); 7 | Matrix operator *(const Matrix& other) { 8 | vector> product(n, vector(n)); 9 | for(int i = 0; i < n; ++i) { 10 | for(int j = 0; j < n; ++j) { 11 | for(int k = 0; k < n; ++k) { 12 | product[i][k] = (product[i][k] + (long long) a[i][j] * other.a[j][k]) % mod; 13 | } 14 | } 15 | } 16 | Matrix retu{product}; 17 | return retu; 18 | } 19 | }; 20 | int main() { 21 | int m, q; 22 | scanf("%d%d%d", &n, &m, &q); 23 | Matrix base; 24 | for(int i = 0; i < m; ++i) { 25 | int a, b; 26 | scanf("%d%d", &a, &b); 27 | base.a[a-1][b-1]++; 28 | } 29 | vector powers{base}; 30 | for(int i = 1; i <= 30; ++i) { 31 | powers.push_back(powers.back() * powers.back()); 32 | } 33 | while(q--) { 34 | int a, b, k; 35 | scanf("%d%d%d", &a, &b, &k); 36 | a--; 37 | b--; 38 | vector dp(n); 39 | dp[a]++; 40 | for(int bit = 0; (1 << bit) <= k; ++bit) { 41 | if(k & (1 << bit)) { 42 | vector new_dp(n); 43 | for(int i = 0; i < n; ++i) { 44 | for(int j = 0; j < n; ++j) { 45 | new_dp[j] = (new_dp[j] + (long long) dp[i] * powers[bit].a[i][j]) % mod; 46 | } 47 | } 48 | dp = new_dp; 49 | } 50 | } 51 | printf("%d\n", dp[b]); 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /matrix-exponentiation/f.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define REP(i,n) for(int i = 0; i < (n); i++) 4 | const long long INF = 3e18L + 5; 5 | int n; 6 | struct Matrix { 7 | vector> a = vector>(n, vector(n, INF)); 8 | Matrix operator *(const Matrix& other) { 9 | Matrix product; 10 | REP(i,n)REP(j,n)REP(k,n) { 11 | product.a[i][k] = min(product.a[i][k], a[i][j] + other.a[j][k]); 12 | // product.a[i][k] = (product.a[i][k] + (long long) a[i][j] * other.a[j][k]) % mod; 13 | } 14 | return product; 15 | } 16 | }; 17 | Matrix expo_power(Matrix a, long long k) { 18 | Matrix product; 19 | REP(i,n) product.a[i][i] = 0; 20 | while(k > 0) { 21 | if(k % 2) { 22 | product = product * a; 23 | } 24 | a = a * a; 25 | k /= 2; 26 | } 27 | return product; 28 | } 29 | int main() { 30 | // F. Min Path 31 | int m; 32 | long long k; 33 | cin >> n >> m >> k; 34 | Matrix single; 35 | // REP(i,n)REP(j,n) { 36 | // single.a[i][j] = INF; 37 | // } 38 | for(int i = 0; i < m; i++) { 39 | int u, v, c; 40 | cin >> u >> v >> c; 41 | single.a[u-1][v-1] = c; 42 | } 43 | Matrix total = expo_power(single, k); 44 | long long answer = INF; 45 | REP(i,n)REP(j,n) { 46 | answer = min(answer, total.a[i][j]); 47 | } 48 | if(answer >= INF / 2) { 49 | cout << "IMPOSSIBLE" << endl; 50 | } 51 | else { 52 | cout << answer << endl; 53 | } 54 | } 55 | // O(N^3 * log(k)) 56 | -------------------------------------------------------------------------------- /GCJ/2021/1C/roaring_years.cpp: -------------------------------------------------------------------------------- 1 | // Roaring Years 2 | // https://codingcompetitions.withgoogle.com/codejam/round/00000000004362d7/00000000007c0f01 3 | #include 4 | using namespace std; 5 | 6 | void test_case() { 7 | long long y; 8 | scanf("%lld", &y); 9 | string helper = to_string(y); 10 | int len = helper.length(); 11 | 12 | __int128 answer = -1; 13 | 14 | auto test = [&](__int128 x) { 15 | if(x > 5'000'000'000'000'000'000LL) { 16 | return; 17 | } 18 | if(x < 1) { 19 | return; 20 | } 21 | __int128 value = x; 22 | do { 23 | x++; 24 | 25 | __int128 tmp = x; 26 | while(tmp > 0) { 27 | value *= 10; 28 | tmp /= 10; 29 | } 30 | value += x; 31 | } while(value <= y); 32 | if(answer == -1 || value < answer) { 33 | answer = value; 34 | } 35 | }; 36 | 37 | __int128 ten = 1; 38 | for(int pref = 1; pref <= len; pref++) { 39 | long long x = atoll(helper.substr(0, pref).c_str()); 40 | test(x); 41 | test(x + 1); 42 | test(ten); 43 | ten *= 10; 44 | for(int i = 1; i <= 30; i++) { 45 | test(ten - i); 46 | } 47 | } 48 | assert(answer > 0); 49 | string s; 50 | while(answer > 0) { 51 | s += '0' + answer % 10; 52 | answer /= 10; 53 | } 54 | reverse(s.begin(), s.end()); 55 | printf("%s\n", s.c_str()); 56 | } 57 | 58 | int main() { 59 | int T; 60 | scanf("%d", &T); 61 | for(int nr = 1; nr <= T; ++nr) { 62 | printf("Case #%d: ", nr); 63 | test_case(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /leetcode/1048-longest-string-chain.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | vector> edges; 3 | vector score; 4 | int longest(int v) { 5 | if(score[v] > 0) { 6 | return score[v]; 7 | } 8 | score[v] = 1; 9 | for(int b : edges[v]) { // O(M) = O(N*L) 10 | score[v] = max(score[v], longest(b) + 1); 11 | } 12 | return score[v]; 13 | } 14 | public: // O(N*L^2) 15 | int longestStrChain(vector& words) { 16 | const int n = words.size(); 17 | edges.clear(); 18 | edges.resize(n); 19 | score.clear(); 20 | score.resize(n); 21 | unordered_map his_position; 22 | for(int i = 0; i < n; i++) { // O(N*L) 23 | his_position[words[i]] = i; 24 | } 25 | for(int i = 0; i < n; i++) { 26 | string s = words[i]; 27 | for(int j = 0; j < (int) s.length(); j++) { 28 | string maybe = s.substr(0, j) + s.substr(j+1); // O(N*L^2) 29 | auto it = his_position.find(maybe); 30 | if(it == his_position.end()) { 31 | continue; 32 | } 33 | edges[it->second].push_back(i); 34 | } 35 | } 36 | int answer = 0; 37 | for(int i = 0; i < n; i++) { 38 | answer = max(answer, longest(i)); 39 | // cout << longest(i) << endl; 40 | } 41 | return answer; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /CSES/Introductory/12-palindrome.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | // if A appears even number of times -> put half at front, half at back 6 | // if B appears even number of times -> put half at front, half at back 7 | vector freq(26); 8 | string s; 9 | cin >> s; 10 | int n = s.length(); 11 | for (char c : s) { 12 | freq[c-'A']++; // we subtract ASCII values 13 | // so we change char A..Z into value 0..25 14 | } 15 | string half; 16 | char mid = '?'; 17 | for (int c = 0; c < 26; c++) { 18 | if (freq[c] % 2 == 1) { 19 | if (n % 2 == 0 || mid != '?') { 20 | cout << "NO SOLUTION\n"; 21 | return 0; 22 | } 23 | else { 24 | mid = 'A' + c; 25 | } 26 | freq[c]--; 27 | } 28 | half += string(freq[c] / 2, 'A' + c); 29 | } 30 | cout << half; 31 | if (mid != '?') { 32 | cout << mid; 33 | } 34 | reverse(half.begin(), half.end()); 35 | cout << half << "\n"; 36 | } 37 | 38 | /* 39 | bool already_mid = false; 40 | int taken = 0; 41 | for (int c = 0; c < 26; c++) { 42 | if (freq[c] % 2 == 1) { 43 | if (n % 2 == 0 || already_mid) { 44 | cout << "NO SOLUTION\n"; 45 | return 0; 46 | } 47 | else { 48 | already_mid = true; 49 | s[n/2] = 'A' + c; 50 | } 51 | freq[c]--; 52 | } 53 | int half = freq[c] / 2; 54 | for (int i = 0; i < half; i++) { 55 | s[taken+i] = s[n-1-taken-i] = 'A' + c; 56 | } 57 | taken += half; 58 | } 59 | cout << s << "\n"; 60 | */ 61 | -------------------------------------------------------------------------------- /PSUT-coding-marathon/gen.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | int r(int a, int b) { 35 | return a + rand() % (b - a + 1); 36 | } 37 | 38 | int main(int argc, char* argv[]) { 39 | srand(atoi(argv[1])); 40 | //~ int n = r(1, 10); 41 | //~ printf("%d\n", n); 42 | //~ for(int i = 0; i < n; ++i) { 43 | //~ printf("%d ", r(1, 4)); 44 | //~ } 45 | //~ puts(""); 46 | int n = r(1, 10); 47 | printf("%d\n", n); 48 | for(int i = 0; i < n; ++i) { 49 | printf("%d ", r(1, 4)); 50 | } 51 | puts(""); 52 | } 53 | -------------------------------------------------------------------------------- /CSES/Introductory/18-raab.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool test_case() { 5 | int n, a, b; 6 | cin >> n >> a >> b; 7 | int ties = n - a - b; 8 | if (ties < 0) { 9 | return false; 10 | } 11 | n -= ties; // that many times, they play the same card 12 | if (n < 0) { 13 | return false; 14 | } 15 | assert(a + b == n); 16 | if (n >= 1 && (a == n || b == n)) { 17 | return false; 18 | } 19 | cout << "YES\n"; 20 | for (int i = 1; i <= n; i++) { 21 | cout << i << " "; 22 | } 23 | for (int i = n + 1; i <= n + ties; i++) { 24 | cout << i << " "; 25 | } 26 | cout << "\n"; 27 | for (int i = 1; i <= n; i++) { 28 | int x = i + a; 29 | if (x > n) { 30 | x -= n; 31 | } 32 | cout << x << " "; 33 | } 34 | for (int i = n + 1; i <= n + ties; i++) { 35 | cout << i << " "; 36 | } 37 | cout << "\n"; 38 | return true; 39 | } 40 | 41 | // b==n-1, a==1 42 | // A=1 B=2 43 | // A=2 B=3 44 | // A=3 B=4 45 | // A=4 B=5 46 | // A=5 B=6 47 | 48 | // A=6 B=1 49 | 50 | // b==n-2, a==2 51 | // A=1 B=3 52 | // A=2 B=4 53 | // A=3 B=5 54 | // A=4 B=6 55 | // A=5 B=1 56 | // A=6 B=2 57 | // } 58 | 59 | int main() { 60 | int T; 61 | cin >> T; 62 | for (int rep = 0; rep < T; rep++) { 63 | if (!test_case()) { 64 | cout << "NO\n"; 65 | } 66 | } 67 | } 68 | 69 | 70 | // n=4 71 | // a=1 72 | // b=2 73 | // ties=1 74 | 75 | 76 | // A plays 4 77 | // B plays 3 78 | 79 | // A plays 1 80 | // B plays 2 81 | 82 | // A plays 2 83 | // B plays 4 84 | 85 | // ... 86 | -------------------------------------------------------------------------------- /AOC-2024/14-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | long long ans[2][2]; 4 | int main() { 5 | vector> pos, vel; 6 | const int W = 101; 7 | const int H = 103; 8 | // p=57,29 v=-7,-96 9 | int px, py, vx, vy; 10 | while (scanf(" p=%d,%d v=%d,%d", &px, &py, &vx, &vy) != EOF) { 11 | pos.emplace_back(px, py); 12 | vel.emplace_back(vx, vy); 13 | // printf("%d..%d\n", px, vy); 14 | // px = ((px + vx * 100) % W + W) % W; 15 | // py = ((py + vy * 100) % H + H) % H; 16 | // if (px != W / 2 && py != H / 2) { 17 | // ans[px>W/2][py>H/2]++; 18 | // } 19 | } 20 | int turn = 0; 21 | while (true) { 22 | turn++; 23 | vector a(H, string(W, ' ')); 24 | for (int i = 0; i < (int) pos.size(); i++) { 25 | int& x = pos[i].first; 26 | int& y = pos[i].second; 27 | x += vel[i].first; 28 | x = ((x % W) + W) % W; 29 | y += vel[i].second; 30 | y = ((y % H) + H) % H; 31 | a[x][y] = 'X'; 32 | } 33 | int cnt = 0; 34 | for (int i = 0; i < H; i++) { 35 | for (int j = 0; j < W; j++) { 36 | if (j < W-1-j && a[i][j] == 'X' && a[i][W-1-j] == 'X') { 37 | cnt++; 38 | } 39 | } 40 | } 41 | if (cnt >= 50) { 42 | printf("%d ", turn); 43 | for (int y = 0; y < W; y++) { 44 | for (int x = 0; x < H; x++) { 45 | printf("%c", a[x][y]); 46 | } 47 | puts(""); 48 | } 49 | puts(""); 50 | fflush(stdout); 51 | return 0; 52 | } 53 | } 54 | 55 | // printf("%lld\n", ans[0][0] * ans[0][1] * ans[1][0] * ans[1][1]); 56 | } 57 | -------------------------------------------------------------------------------- /AOC-2024/12.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | char s[1005][1005]; 4 | bool vis[1005][1005]; 5 | int H, W; 6 | vector> dirs{{-1,0},{0,1},{1,0},{0,-1}}; 7 | 8 | bool inside(int row, int col) { 9 | return 0 <= row && row < H && 0 <= col && col < W; 10 | } 11 | 12 | void dfs(int row, int col, int& area, int& per) { 13 | vis[row][col] = true; 14 | area++; 15 | 16 | auto good = [&](pair dir) { 17 | int r2 = row + dir.first; 18 | int c2 = col + dir.second; 19 | return inside(r2, c2) && s[r2][c2] == s[row][col]; 20 | }; 21 | 22 | for (int i = 0; i < 4; i++) { 23 | pair dir = dirs[i]; 24 | pair dir2 = dirs[(i+1)%4]; 25 | if (!good(dir) && !good(dir2)) { 26 | per++; 27 | } 28 | if (good(dir) && good(dir2) && !good(make_pair(dir.first+dir2.first, dir.second+dir2.second))) { 29 | per++; 30 | } 31 | } 32 | 33 | for (pair dir : dirs) { 34 | int r2 = row + dir.first; 35 | int c2 = col + dir.second; 36 | if (good(dir) && !vis[r2][c2]) { 37 | dfs(r2, c2, area, per); 38 | } 39 | } 40 | } 41 | 42 | int main() { 43 | for (int row = 0; scanf("%s", s[row]) != EOF; row++) { 44 | H = row + 1; 45 | W = strlen(s[row]); 46 | } 47 | long long answer = 0; 48 | for (int row = 0; row < H; row++) { 49 | for (int col = 0; col < W; col++) { 50 | if (!vis[row][col]) { 51 | int area = 0, per = 0; 52 | dfs(row, col, area, per); 53 | answer += area * per; 54 | } 55 | } 56 | } 57 | printf("%lld\n", answer); 58 | } 59 | -------------------------------------------------------------------------------- /atcoder-dp/a.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | const int INF = 1e9 + 5; 35 | 36 | int main() { 37 | int n; 38 | scanf("%d", &n); 39 | vector h(n); 40 | for(int& x : h) { 41 | scanf("%d", &x); 42 | } 43 | vector dp(n, INF); 44 | dp[0] = 0; 45 | for(int i = 0; i < n; ++i) { 46 | for(int j : {i + 1, i + 2}) { 47 | if(j < n) { 48 | dp[j] = min(dp[j], dp[i] + abs(h[i] - h[j])); 49 | } 50 | } 51 | } 52 | printf("%d\n", dp[n-1]); 53 | } 54 | -------------------------------------------------------------------------------- /PSUT-coding-marathon/b.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | 35 | 36 | int main() { 37 | int n; 38 | int weakest = INT_MAX; 39 | cin >> n; 40 | for(int i = 0; i < n; ++i) { 41 | int x; 42 | cin >> x; 43 | weakest = min(weakest, x); 44 | } 45 | int easiest = INT_MAX; 46 | for(int i = 0; i < 10; ++i) { 47 | int x; 48 | cin >> x; 49 | easiest = min(easiest, x); 50 | } 51 | if(easiest <= weakest) { 52 | cout << 10 << endl; 53 | } 54 | else { 55 | cout << weakest << endl; 56 | } 57 | } 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /and-reachability/ac.cpp: -------------------------------------------------------------------------------- 1 | // C. And Reachability, CF #562 (Div. 1) 2 | // https://codeforces.com/contest/1168/problem/C 3 | // O(n*log^2(MAX_A)) 4 | #include 5 | using namespace std; 6 | 7 | const int MAX_N = 3e5 + 5; 8 | int a[MAX_N]; 9 | int nxt[MAX_N][19]; 10 | int recent[19]; 11 | /* 12 | nxt[i][b] - smallest index j that: 13 | 1) j is reachable from i, and 14 | 2) a[j] has b-th bit on 15 | 16 | recent[b] - while we iterate from N-1 to 0, most recent position j 17 | such that a[j] has b-th bit on 18 | */ 19 | int main() { 20 | int n, q; 21 | scanf("%d%d", &n, &q); 22 | for(int i = 0; i < n; ++i) { 23 | scanf("%d", &a[i]); 24 | } 25 | for(int bit = 0; bit < 19; ++bit) { 26 | recent[bit] = n; 27 | } 28 | for(int i = n - 1; i >= 0; --i) { 29 | for(int bit = 0; bit < 19; ++bit) { 30 | nxt[i][bit] = n; 31 | } 32 | for(int bit = 0; bit < 19; ++bit) { 33 | if(a[i] & (1 << bit)) { 34 | int where = recent[bit]; 35 | if(where != n) { 36 | nxt[i][bit] = min(nxt[i][bit], where); 37 | for(int b2 = 0; b2 < 19; ++b2) { 38 | nxt[i][b2] = min(nxt[i][b2], nxt[where][b2]); 39 | } 40 | } 41 | recent[bit] = i; 42 | } 43 | } 44 | } 45 | while(q--) { 46 | int x, y; 47 | scanf("%d%d", &x, &y); 48 | --x; // change numbering from [1,N] to [0,N-1] 49 | --y; 50 | bool ok = false; 51 | for(int bit = 0; bit < 19; ++bit) { 52 | if(a[y] & (1 << bit)) { 53 | if(nxt[x][bit] <= y) { 54 | ok = true; 55 | break; 56 | } 57 | } 58 | } 59 | puts(ok ? "Shi" : "Fou"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lectures/binary-search/search-in-rotated-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | // Search in Rotated Sorted Array, https://leetcode.com/explore/learn/card/binary-search/125/template-i/952/ 2 | // This is the harder of two rotated-array problems in Leetcode. 3 | 4 | // There are two options: 5 | // 1) First find the rotation (the position of the smallest element) and then find the target value in one of the parts. This approach requires one binary search and then another different binary search. 6 | // 2) Run one binary search with more complicated if-conditions to look for the number - this is what my code does. You should try yourself the first approach. 7 | 8 | class Solution { 9 | public: 10 | int search(vector& a, int target) { 11 | // For each number we can check if we should go to the left/right by comparing it with target and with a[0]. Also, comparing target with a[0] tells us in which part (big or small numbers) the target is. 12 | int n = a.size(); 13 | int left = 0, right = n - 1; 14 | while(left <= right) { 15 | int mid = left + (right - left) / 2; 16 | if(a[mid] == target) { 17 | return mid; // no need to store the answer, just return it 18 | } 19 | if((target >= a[0] && (a[mid] >= target || a[mid] < a[0])) || 20 | (target < a[0] && (a[mid] < a[0] && a[mid] >= target))) { 21 | right = mid - 1; 22 | } 23 | else { 24 | left = mid + 1; 25 | } 26 | } 27 | return -1; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /atcoder-dp/b.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | const int INF = 1e9 + 5; 35 | 36 | int main() { 37 | int n; 38 | scanf("%d", &n); 39 | int k; 40 | scanf("%d", &k); 41 | vector h(n); 42 | for(int& x : h) { 43 | scanf("%d", &x); 44 | } 45 | vector dp(n, INF); 46 | dp[0] = 0; 47 | for(int i = 0; i < n; ++i) { 48 | for(int j = i + 1; j <= i + k; ++j) { 49 | if(j < n) { 50 | dp[j] = min(dp[j], dp[i] + abs(h[i] - h[j])); 51 | } 52 | } 53 | } 54 | printf("%d\n", dp[n-1]); 55 | } 56 | -------------------------------------------------------------------------------- /atcoder-dp/k.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | // dp[i] - TRUE if the first player wins if there are i stones remaining 35 | 36 | int main() { 37 | int n, k; 38 | scanf("%d%d", &n, &k); 39 | vector a(n); 40 | for(int& x : a) { 41 | scanf("%d", &x); 42 | } 43 | vector dp(k + 1); 44 | for(int stones = 0; stones <= k; ++stones) { 45 | for(int x : a) { 46 | if(stones >= x && !dp[stones-x]) { 47 | dp[stones] = true; 48 | } 49 | } 50 | } 51 | 52 | puts(dp[k] ? "First" : "Second"); 53 | } 54 | -------------------------------------------------------------------------------- /AOC-2024/09-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct Block { 5 | int id, size, pos; 6 | }; 7 | 8 | int main() { 9 | string s; 10 | cin >> s; 11 | int n = s.length(); 12 | int pos = 0; 13 | vector blocks; 14 | for (int i = 0; i < n; i++) { 15 | int digit = s[i] - '0'; 16 | if (i % 2 == 0) { 17 | blocks.push_back(Block{i/2, digit, pos}); 18 | } 19 | pos += digit; 20 | } 21 | string out(pos, '.'); 22 | long long answer = 0; 23 | while ((int) blocks.size() >= 2) { 24 | Block me = blocks.back(); 25 | // blocks.pop_back(); 26 | bool inserted = false; 27 | for (int i = 0; i < (int) blocks.size() - 1; i++) { 28 | int A = blocks[i].pos + blocks[i].size; 29 | int B = blocks[i+1].pos; 30 | if (B - A >= me.size) { 31 | inserted = true; 32 | me.pos = A; 33 | blocks.pop_back(); 34 | blocks.insert(blocks.begin() + i + 1, me); 35 | break; 36 | } 37 | } 38 | if (!inserted) { 39 | blocks.pop_back(); 40 | // me.pos = blocks.back().pos + blocks.back().size; 41 | cout << me.pos << " " << me.id << endl; 42 | // blocks.push_back(me); 43 | for (int j = 0; j < me.size; j++) { 44 | answer += (me.pos+j) * me.id; 45 | out[me.pos+j] = '0' + me.id; 46 | } 47 | // break; 48 | } 49 | } 50 | Block me = blocks[0]; 51 | for (int j = 0; j < me.size; j++) { 52 | out[me.pos+j] = '0' + me.id; 53 | // answer += (me.pos+j) * me.id; 54 | } 55 | cout << out << "\n"; 56 | // for (Block block : blocks) { 57 | // answer += block.pos * block.id; 58 | // } 59 | cout << answer << "\n"; 60 | } 61 | -------------------------------------------------------------------------------- /lca.cpp: -------------------------------------------------------------------------------- 1 | // video https://youtu.be/dOAxrhAUIhA 2 | // problem https://www.spoj.com/problems/LCASQ/ 3 | #include 4 | using namespace std; 5 | 6 | const int MAX_N = 10000; 7 | const int LOG = 14; 8 | vector children[MAX_N]; 9 | int up[MAX_N][LOG]; // up[v][j] is 2^j-th ancestor of v 10 | int depth[MAX_N]; 11 | 12 | void dfs(int a) { 13 | for(int b : children[a]) { 14 | depth[b] = depth[a] + 1; 15 | up[b][0] = a; // a is parent of b 16 | for(int j = 1; j < LOG; j++) { 17 | up[b][j] = up[up[b][j-1]][j-1]; 18 | } 19 | dfs(b); 20 | } 21 | } 22 | 23 | int get_lca(int a, int b) { // O(log(N)) 24 | if(depth[a] < depth[b]) { 25 | swap(a, b); 26 | } 27 | // 1) Get same depth. 28 | int k = depth[a] - depth[b]; 29 | for(int j = LOG - 1; j >= 0; j--) { 30 | if(k & (1 << j)) { 31 | a = up[a][j]; // parent of a 32 | } 33 | } 34 | // 2) if b was ancestor of a then now a==b 35 | if(a == b) { 36 | return a; 37 | } 38 | // 3) move both a and b with powers of two 39 | for(int j = LOG - 1; j >= 0; j--) { 40 | if(up[a][j] != up[b][j]) { 41 | a = up[a][j]; 42 | b = up[b][j]; 43 | } 44 | } 45 | return up[a][0]; 46 | } 47 | 48 | int main() { 49 | int n; 50 | cin >> n; 51 | for(int v = 0; v < n; ++v) { 52 | // read children of v 53 | int cnt; 54 | cin >> cnt; 55 | for(int i = 0; i < cnt; i++) { 56 | int c; 57 | cin >> c; 58 | children[v].push_back(c); 59 | } 60 | } 61 | dfs(0); 62 | int q; 63 | cin >> q; 64 | for(int i = 0; i < q; i++) { 65 | int a, b; 66 | cin >> a >> b; 67 | cout << get_lca(a, b) << "\n"; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /POI/22-movie-goer.cpp: -------------------------------------------------------------------------------- 1 | // Movie-goer problem from POI 22, https://szkopul.edu.pl/problemset/problem/k-RYEjhwNTo_XdaCidXQUGMU/site/?key=statement 2 | // video link: https://youtu.be/rF13507mRp8 3 | #include 4 | using namespace std; 5 | struct Node { 6 | long long sum, prefMax; 7 | void merge(Node left, Node right) { 8 | sum = left.sum + right.sum; 9 | prefMax = max(left.prefMax, left.sum + right.prefMax); 10 | } 11 | }; 12 | const int INF = 1e9 + 5; 13 | int main() { 14 | int n, m; 15 | scanf("%d%d", &n, &m); 16 | vector movie(n); 17 | for(int i = 0; i < n; i++) { 18 | scanf("%d", &movie[i]); 19 | movie[i]--; 20 | } 21 | vector value(m); 22 | for(int i = 0; i < m; i++) { 23 | scanf("%d", &value[i]); 24 | } 25 | 26 | int BASE = 1; 27 | while(BASE < n) { 28 | BASE *= 2; 29 | } 30 | vector tree(2 * BASE); 31 | auto set = [&](int i, int val) { 32 | tree[BASE+i] = Node{val, max(0, val)}; 33 | for(int j = (BASE + i) / 2; j >= 1; j /= 2) { 34 | tree[j].merge(tree[2*j], tree[2*j+1]); 35 | } 36 | }; 37 | 38 | long long answer = 0; 39 | vector> where(m, {INF, INF}); 40 | 41 | for(int i = n - 1; i >= 0; i--) { 42 | int m_id = movie[i]; 43 | vector& vec = where[m_id]; 44 | int sec_last = vec[(int) vec.size() - 2]; 45 | int last = vec.back(); 46 | 47 | if(sec_last < INF) { 48 | set(sec_last, 0); 49 | } 50 | if(last < INF) { 51 | set(last, -value[m_id]); 52 | } 53 | set(i, value[m_id]); 54 | 55 | answer = max(answer, tree[1].prefMax); 56 | vec.push_back(i); 57 | } 58 | 59 | printf("%lld\n", answer); 60 | } 61 | -------------------------------------------------------------------------------- /AOC-2024/18-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int INF = 1e9 + 5; 5 | 6 | const int S = 71; 7 | bool vis[S][S]; 8 | 9 | // O(N^2), linear Dijkstra to maximize ids of blocked cells used 10 | 11 | int main() { 12 | vector> in; 13 | const int N = 3450; 14 | vector> value(S, vector(S, N+1)); 15 | vector> dist(S, vector(S, 0)); 16 | for (int i = 0; i < N; i++) { 17 | int x, y; 18 | scanf(" %d,%d", &x, &y); 19 | in.emplace_back(x, y); 20 | value[x][y] = i + 1; 21 | } 22 | 23 | // for (int i = 0; i < S; i++) { 24 | // for (int j = 0; j < S; j++) { 25 | // printf("%d ", value[i][j]); 26 | // } 27 | // puts(""); 28 | // } 29 | 30 | vector> inv[N+3]; 31 | dist[0][0] = value[0][0]; 32 | inv[dist[0][0]].emplace_back(0, 0); 33 | 34 | for (int v = N + 1; v >= 0; v--) { 35 | for (int z = 0; z < (int) inv[v].size(); z++) { 36 | pair me = inv[v][z]; 37 | int r = me.first; 38 | int c = me.second; 39 | if (dist[r][c] != v) { 40 | continue; 41 | } 42 | for (pair dir : vector>{{-1,0},{1,0},{0,1},{0,-1}}) { 43 | int r2 = r + dir.first; 44 | int c2 = c + dir.second; 45 | if (0 <= min(r2, c2) && max(r2, c2) < S) { 46 | int x = min(v, value[r2][c2]); 47 | if (x > dist[r2][c2]) { 48 | dist[r2][c2] = x; 49 | inv[x].emplace_back(r2, c2); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | int id = dist[S-1][S-1] - 1; 56 | cerr << "id = " << id << "\n"; // 0-based 57 | printf("%d,%d\n", in[id].first, in[id].second); 58 | } 59 | -------------------------------------------------------------------------------- /atcoder-dp/l.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | const int nax = 3005; 35 | ll dp[nax][nax]; 36 | 37 | int main() { 38 | int n; 39 | scanf("%d", &n); 40 | vector a(n); 41 | for(int i = 0; i < n; ++i) { 42 | scanf("%d", &a[i]); 43 | } 44 | // dp[0][n-1] 45 | for(int L = n - 1; L >= 0; --L) { 46 | for(int R = L; R < n; ++R) { 47 | if(L == R) { 48 | dp[L][R] = a[L]; 49 | } 50 | else { 51 | dp[L][R] = max(a[L] - dp[L+1][R], a[R] - dp[L][R-1]); 52 | } 53 | } 54 | } 55 | printf("%lld\n", dp[0][n-1]); 56 | } 57 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/26-LCS-longest-common-subsequence.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | map, int> answer; 3 | string text1, text2; 4 | int my_LCS(int len1, int len2) { 5 | if(len1 == 0 || len2 == 0) { 6 | return 0; 7 | } 8 | pair my_state{len1, len2}; 9 | auto it = answer.find(my_state); 10 | if(it != answer.end()) { 11 | return it->second; 12 | } 13 | if(text1[len1-1] == text2[len2-1]) { 14 | return answer[my_state] = 1 + my_LCS(len1-1, len2-1); 15 | } 16 | return answer[my_state] = max(my_LCS(len1-1, len2), my_LCS(len1, len2-1)); 17 | } 18 | int longestCommonSubsequence(string _text1, string _text2) { 19 | text1 = _text1; 20 | text2 = _text2; 21 | return my_LCS(text1.length(), text2.length()); 22 | } 23 | 24 | /* 25 | if(text1.empty() || text2.empty()) { 26 | return 0; 27 | } 28 | pair my_state{text1.length(),text2.length()}; 29 | auto it = answer.find(my_state); 30 | if(it != answer.end()) { 31 | return it->second; 32 | } 33 | if(text1.back() == text2.back()) { 34 | text1.pop_back(); 35 | text2.pop_back(); 36 | return answer[my_state] = 1 + longestCommonSubsequence(text1, text2); 37 | } 38 | return answer[my_state = max(longestCommonSubsequence(text1, string(text2.begin(), text2.end()-1)), 39 | longestCommonSubsequence(text2, string(text1.begin(), text1.end()-1)));*/ 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /AOC-2024/02-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // O(T * LEN^2) if we try removing every element 5 | // O(T * LEN) 6 | 7 | bool isOK(vector a) { 8 | int k = (int) a.size(); 9 | bool ok = true; 10 | bool only_inc = true; 11 | bool only_dec = true; 12 | for (int j = 0; j < k - 1; j++) { 13 | int diff = a[j+1] - a[j]; 14 | if (diff > 0) { 15 | only_dec = false; 16 | } 17 | if (diff < 0) { 18 | only_inc = false; 19 | } 20 | if (!(1 <= abs(diff) && abs(diff) <= 3)) { 21 | ok = false; 22 | break; 23 | } 24 | } 25 | return ok && (only_inc || only_dec); 26 | } 27 | 28 | int main() { 29 | int T = 1000; 30 | int answer = 0; 31 | while (T--) { 32 | vector a; 33 | while (true) { 34 | int x; 35 | scanf("%d", &x); 36 | a.push_back(x); 37 | char c; 38 | scanf("%c", &c); 39 | if (c == '\n') { 40 | break; 41 | } 42 | } 43 | bool anyOK = false; 44 | auto consider = [&](int i) { 45 | vector b = a; 46 | b.erase(b.begin() + i); 47 | if (isOK(b)) { 48 | anyOK = true; 49 | } 50 | }; 51 | 52 | int k = a.size(); 53 | consider(0); 54 | for (int i = 0; i < k - 1; i++) { 55 | int diff = a[i+1] - a[i]; 56 | if (abs(diff) < 1 || abs(diff) > 3) { 57 | consider(i); 58 | consider(i+1); 59 | break; 60 | } 61 | if (i + 2 < k) { 62 | int diff2 = a[i+2] - a[i+1]; 63 | if ((diff > 0) != (diff2 > 0)) { 64 | consider(i); 65 | consider(i+1); 66 | consider(i+2); 67 | break; 68 | } 69 | } 70 | } 71 | if (anyOK) { 72 | answer++; 73 | } 74 | } 75 | printf("%d\n", answer); 76 | } 77 | -------------------------------------------------------------------------------- /AOC-2024/13-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | char s[105]; 5 | long long answer = 0; 6 | while (scanf("%s", s) != EOF) { 7 | scanf(" %s", s); 8 | int ax, ay, bx, by; 9 | scanf(" X+%d, ", &ax); 10 | scanf(" Y+%d", &ay); 11 | scanf(" %s", s); 12 | scanf(" %s", s); 13 | scanf(" X+%d, ", &bx); 14 | scanf(" Y+%d", &by); 15 | scanf(" %s", s); 16 | long long px, py; 17 | scanf(" X=%lld, ", &px); 18 | scanf(" Y=%lld", &py); 19 | px += 10000000000000LL; 20 | py += 10000000000000LL; 21 | // printf("%d %d\n", ax, ay); 22 | // printf("%d %d\n", bx, by); 23 | 24 | // i * ax + j * bx = px 25 | // i = (px - j * bx) / ax 26 | // i * ay + j * by = py 27 | // (px - j * bx) / ax * ay + j * by = py 28 | // (px - j * bx) * ay + j * by * ax = py * ax 29 | // px * ay - j * bx * ay + j * by * ax = py * ax 30 | // j * (by * ax - bx * ay) = py * ax - px * ay 31 | 32 | long long j = (py * ax - px * ay) / (by * ax - bx * ay); 33 | long long i = (py * bx - px * by) / (ay * bx - ax * by); 34 | if (i * ax + j * bx == px) { 35 | if (i * ay + j * by == py) { 36 | answer += 3 * i + j; 37 | } 38 | } 39 | // for (int i = 0; i * ax <= px; i++) { 40 | // assert(bx != 0); 41 | // int j = (px - i * ax) / bx; 42 | // if (i * ax + j * bx == px) { 43 | // if (i * ay + j * by == py) { 44 | // assert(i <= 100 && j <= 100); 45 | // answer += 3 * i + j; 46 | // assert(j == (py * ax - px * ay) / (by * ax - bx * ay)); 47 | // assert(i == (py * bx - px * by) / (ay * bx - ax * by)); 48 | // } 49 | // } 50 | // } 51 | } 52 | printf("%lld\n", answer); 53 | } 54 | -------------------------------------------------------------------------------- /POI/tree-rotations/kd_ac.cpp: -------------------------------------------------------------------------------- 1 | // POI 18-2, Tree Rotations 2 | // O(N * log^2(N)) 3 | #include 4 | using namespace std; 5 | 6 | #include 7 | #include 8 | using namespace __gnu_pbds; 9 | using ordered_set = tree, rb_tree_tag,tree_order_statistics_node_update>; 10 | 11 | const int NAX = 2e5 + 5; 12 | ordered_set s[NAX]; 13 | int next_to_take = 0; 14 | long long answer; 15 | 16 | int rec() { 17 | int x; 18 | scanf("%d", &x); 19 | if(x > 0) { 20 | int me = next_to_take++; 21 | s[me].insert(x); 22 | return me; 23 | } 24 | int L = rec(); 25 | int R = rec(); 26 | const long long pairs = (long long) s[L].size() * (long long) s[R].size(); 27 | if(s[L].size() > s[R].size()) { 28 | swap(L, R); 29 | } 30 | //~ for(int a : s[L]) { 31 | //~ printf("%d ", a); 32 | //~ } 33 | //~ printf(" with "); 34 | //~ for(int a : s[R]) { 35 | //~ printf("%d ", a); 36 | //~ } 37 | //~ puts(""); 38 | long long inversions = 0; 39 | for(int a : s[L]) { 40 | inversions += s[R].order_of_key(a); // the number of elements strictly smaller than a 41 | } 42 | //~ printf("%lld\n", inversions); 43 | //~ puts(""); 44 | for(int a : s[L]) { 45 | s[R].insert(a); 46 | } 47 | s[L].clear(); // better to swap with an empty set, to trigger the desctructor and free the memory 48 | answer += min(inversions, pairs - inversions); 49 | return R; 50 | } 51 | 52 | int main() { 53 | int n; 54 | scanf("%d", &n); 55 | rec(); 56 | printf("%lld\n", answer); 57 | } 58 | -------------------------------------------------------------------------------- /GCJ/2020/qual/B-nesting-depth.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | 33 | 34 | void test_case() { 35 | char s[105]; 36 | scanf("%s", s); 37 | int n = strlen(s); 38 | string answer; 39 | int depth = 0; 40 | for(int i = 0; i < n; ++i) { 41 | int digit = s[i] - '0'; 42 | for(int i = 0; i < max(0, digit - depth); ++i) { 43 | printf("("); 44 | } 45 | for(int i = 0; i < max(0, depth - digit); ++i) { 46 | printf(")"); 47 | } 48 | printf("%d", digit); 49 | depth = digit; 50 | } 51 | for(int i = 0; i < depth; ++i) { 52 | printf(")"); 53 | } 54 | puts(""); 55 | } 56 | 57 | int main() { 58 | int T; 59 | scanf("%d", &T); 60 | for(int nr = 1; nr <= T; nr++) { 61 | printf("Case #%d: ", nr); 62 | test_case(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /painting-the-fence/solution1.cpp: -------------------------------------------------------------------------------- 1 | // solution 1, O(n*q + q^2) 2 | #include "bits/stdc++.h" 3 | using namespace std; 4 | int main() { 5 | int n, q; 6 | scanf("%d%d", &n, &q); 7 | vector> intervals(q); 8 | vector cnt(n); 9 | for(pair& p : intervals) { 10 | scanf("%d%d", &p.first, &p.second); 11 | --p.first; 12 | --p.second; 13 | for(int i = p.first; i <= p.second; ++i) { 14 | ++cnt[i]; 15 | } 16 | } 17 | int answer = 0; 18 | for(int A = 0; A < q; ++A) { 19 | int count_positive = 0; 20 | vector ones(n); 21 | for(int i = intervals[A].first; i <= intervals[A].second; ++i) { 22 | --cnt[i]; 23 | } 24 | 25 | for(int i = 0; i < n; ++i) { 26 | if(cnt[i] > 0) { 27 | ++count_positive; 28 | } 29 | if(cnt[i] == 1) { 30 | ++ones[i]; 31 | } 32 | } 33 | // prefix sums on 'ones' 34 | for(int i = 1; i < n; ++i) { 35 | ones[i] += ones[i-1]; 36 | } 37 | auto get_sum = [&](int L, int R) { // sum of interval [L,R] 38 | return ones[R] - (L ? ones[L-1] : 0); 39 | }; 40 | 41 | for(int B = A + 1; B < q; ++B) { 42 | int lost_ones = get_sum(intervals[B].first, intervals[B].second); 43 | answer = max(answer, count_positive - lost_ones); 44 | } 45 | 46 | // roll back the decreases of 'cnt' 47 | for(int i = intervals[A].first; i <= intervals[A].second; ++i) { 48 | ++cnt[i]; 49 | } 50 | } 51 | printf("%d\n", answer); 52 | } 53 | -------------------------------------------------------------------------------- /AOC-2020/20-jigsaw/in: -------------------------------------------------------------------------------- 1 | Tile 2311: 2 | ..##.#..#. 3 | ##..#..... 4 | #...##..#. 5 | ####.#...# 6 | ##.##.###. 7 | ##...#.### 8 | .#.#.#..## 9 | ..#....#.. 10 | ###...#.#. 11 | ..###..### 12 | 13 | Tile 1951: 14 | #.##...##. 15 | #.####...# 16 | .....#..## 17 | #...###### 18 | .##.#....# 19 | .###.##### 20 | ###.##.##. 21 | .###....#. 22 | ..#.#..#.# 23 | #...##.#.. 24 | 25 | Tile 1171: 26 | ####...##. 27 | #..##.#..# 28 | ##.#..#.#. 29 | .###.####. 30 | ..###.#### 31 | .##....##. 32 | .#...####. 33 | #.##.####. 34 | ####..#... 35 | .....##... 36 | 37 | Tile 1427: 38 | ###.##.#.. 39 | .#..#.##.. 40 | .#.##.#..# 41 | #.#.#.##.# 42 | ....#...## 43 | ...##..##. 44 | ...#.##### 45 | .#.####.#. 46 | ..#..###.# 47 | ..##.#..#. 48 | 49 | Tile 1489: 50 | ##.#.#.... 51 | ..##...#.. 52 | .##..##... 53 | ..#...#... 54 | #####...#. 55 | #..#.#.#.# 56 | ...#.#.#.. 57 | ##.#...##. 58 | ..##.##.## 59 | ###.##.#.. 60 | 61 | Tile 2473: 62 | #....####. 63 | #..#.##... 64 | #.##..#... 65 | ######.#.# 66 | .#...#.#.# 67 | .######### 68 | .###.#..#. 69 | ########.# 70 | ##...##.#. 71 | ..###.#.#. 72 | 73 | Tile 2971: 74 | ..#.#....# 75 | #...###... 76 | #.#.###... 77 | ##.##..#.. 78 | .#####..## 79 | .#..####.# 80 | #..#.#..#. 81 | ..####.### 82 | ..#.#.###. 83 | ...#.#.#.# 84 | 85 | Tile 2729: 86 | ...#.#.#.# 87 | ####.#.... 88 | ..#.#..... 89 | ....#..#.# 90 | .##..##.#. 91 | .#.####... 92 | ####.#.#.. 93 | ##.####... 94 | ##..#.##.. 95 | #.##...##. 96 | 97 | Tile 3079: 98 | #.#.#####. 99 | .#..###### 100 | ..#....... 101 | ######.... 102 | ####.#..#. 103 | .#...#.##. 104 | #.#####.## 105 | ..#.###... 106 | ..#....... 107 | ..#.###... 108 | -------------------------------------------------------------------------------- /matrix-exponentiation/e2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int A = 65; 4 | #define REP(i, n) for(int i = 0; i < (n); i++) 5 | struct Matrix { 6 | vector> a; 7 | Matrix() { 8 | a.resize(A, vector(A)); 9 | } 10 | Matrix operator *(Matrix other) { 11 | Matrix product = Matrix(); 12 | REP(i, A) { 13 | REP(j, A) { 14 | REP(k, A) { 15 | product.a[i][k] += a[i][j] * other.a[j][k]; 16 | } 17 | } 18 | } 19 | return product; 20 | } 21 | }; 22 | Matrix expo_power(Matrix a, long long n) { 23 | Matrix res = Matrix(); 24 | for(int i = 0; i < A; ++i) { 25 | res.a[i][i] = 1; 26 | } 27 | while(n) { 28 | if(n % 2) { 29 | res = res * a; 30 | } 31 | n /= 2; 32 | a = a * a; 33 | } 34 | return res; 35 | } 36 | int main() { 37 | long long n; 38 | cin >> n; 39 | Matrix single = Matrix(); 40 | single.a[64][64] = 1; // the answer moves on to next step 41 | for(int cell = 0; cell < 64; ++cell) { 42 | single.a[cell][64] = 1; // add to the answer 43 | for(int cell2 = 0; cell2 < 64; ++cell2) { 44 | int row = cell / 8; 45 | int col = cell % 8; 46 | int r2 = cell2 / 8; 47 | int c2 = cell2 % 8; 48 | int d_row = abs(row - r2); 49 | int d_col = abs(col - c2); 50 | if((d_row == 2 && d_col == 1) || (d_row == 1 && d_col == 2)) { 51 | single.a[cell][cell2] = 1; 52 | } 53 | } 54 | } 55 | Matrix total = expo_power(single, n + 1); // n+1 because answer is taken as sum from previous iteration 56 | cout << total.a[0][64] << endl; 57 | /*Matrix total = expo_power(single, n); 58 | unsigned int answer = 0; 59 | for(int i = 0; i < A; ++i) { 60 | answer += total.a[0][i]; 61 | } 62 | cout << answer << endl;*/ 63 | } 64 | -------------------------------------------------------------------------------- /leetcode/1224-frequency.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/maximum-equal-frequency/ 2 | class Solution { 3 | public: 4 | int maxEqualFreq(vector& nums) { 5 | const int n = nums.size(); 6 | int answer = 0; 7 | map freq; 8 | map freq_freq; 9 | for(int i = 0; i < n; i++) { 10 | int x = nums[i]; 11 | if(freq[x] > 0) { 12 | if(--freq_freq[freq[x]] == 0) { 13 | freq_freq.erase(freq[x]); 14 | } 15 | } 16 | ++freq[nums[i]]; 17 | ++freq_freq[freq[x]]; 18 | bool flag = false; 19 | if((int) freq_freq.size() <= 2) { 20 | // 3 3 3 3 21 | pair p = *freq_freq.begin(); 22 | if((int) freq_freq.size() == 1) { 23 | if(p.first == 1) { 24 | flag = true; // (1, 1, 1) -> (1, 1) 25 | } 26 | // (5) 27 | if(p.second == 1) { 28 | flag = true; 29 | } 30 | } 31 | else { 32 | pair q = *freq_freq.rbegin(); 33 | // 5 5 5 1 34 | if(p.first == 1 && p.second == 1) { 35 | flag = true; 36 | } 37 | // 5 4 4 4 4 38 | if(p.first + 1 == q.first && q.second == 1) { 39 | flag = true; 40 | } 41 | } 42 | } 43 | if(flag) { 44 | answer = i + 1; 45 | } 46 | } 47 | return answer; 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /AOC-2024/06-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector> dirs = {{-1,0}, {0,1}, {1,0}, {0,-1}}; 5 | 6 | // O((H*W)^2) 7 | 8 | int main() { 9 | int H = 130; 10 | vector a(H); 11 | for (int i = 0; i < H; i++) { 12 | cin >> a[i]; 13 | } 14 | int W = a[0].length(); 15 | 16 | pair start_me{-1, -1}; 17 | for (int row = 0; row < H; row++) { 18 | for (int col = 0; col < W; col++) { 19 | if (a[row][col] == '^') { 20 | start_me = {row, col}; 21 | a[row][col] = '.'; 22 | } 23 | } 24 | } 25 | 26 | auto solveCycle = [&]() { 27 | pair me = start_me; 28 | int dir = 0; 29 | 30 | vector vis(H * W * 4); 31 | // int turns = 0; 32 | while (true) { 33 | // turns++; 34 | // if (turns == H * W * 4) { 35 | // return true; 36 | // } 37 | int hash = (me.first * W + me.second) * 4 + dir; 38 | if (vis[hash]) { 39 | return true; 40 | } 41 | vis[hash] = true; 42 | int r2 = me.first + dirs[dir].first; 43 | int c2 = me.second + dirs[dir].second; 44 | if (!(0 <= r2 && r2 < H && 0 <= c2 && c2 < W)) { 45 | return false; // outside 46 | } 47 | if (a[r2][c2] == '.') { 48 | me = {r2, c2}; 49 | } 50 | else { 51 | dir = (dir + 1) % 4; 52 | } 53 | } 54 | }; 55 | 56 | int answer = 0; 57 | for (int row = 0; row < H; row++) { 58 | for (int col = 0; col < W; col++) { 59 | if (a[row][col] == '.' && start_me != make_pair(row, col)) { 60 | // cout << row << " " << col << endl; 61 | a[row][col] = '#'; 62 | if (solveCycle()) { 63 | // cout << row << " " << col << endl; 64 | answer++; 65 | } 66 | a[row][col] = '.'; 67 | } 68 | } 69 | } 70 | cout << answer << "\n"; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/17-number-of-islands.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int numIslands(vector>& grid) { 4 | if(grid.empty() || grid[0].empty()) { 5 | return 0; 6 | } 7 | int H = grid.size(); 8 | int W = grid[0].size(); 9 | int answer = 0; 10 | auto inside = [&](int row, int col) { 11 | return 0 <= row && row < H && 0 <= col && col < W; 12 | }; 13 | vector> directions{{1,0},{0,1},{-1,0},{0,-1}}; 14 | // vis[H][W] 15 | vector> vis(H, vector(W)); 16 | for(int row = 0; row < H; row++) { 17 | for(int col = 0; col < W; col++) { 18 | if(!vis[row][col] && grid[row][col] == '1') { 19 | answer++; 20 | queue> q; 21 | q.push({row, col}); 22 | vis[row][col] = true; 23 | while(!q.empty()) { 24 | pair p = q.front(); 25 | q.pop(); 26 | // p.first, p.second 27 | for(pair dir : directions) { 28 | int new_row = p.first + dir.first; 29 | int new_col = p.second + dir.second; 30 | if(inside(new_row, new_col) && !vis[new_row][new_col] && grid[new_row][new_col] == '1') { 31 | q.push({new_row, new_col}); 32 | vis[new_row][new_col] = true; 33 | } 34 | } 35 | } 36 | } 37 | } 38 | } 39 | return answer; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/20-construct-BST-from-traversal.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | * }; 9 | */ 10 | class Solution { 11 | private: 12 | TreeNode* helper(const vector& preorder, int& id, int limit) { 13 | if(id == (int) preorder.size() || preorder[id] > limit) { 14 | return NULL; 15 | } 16 | int root_value = preorder[id]; 17 | TreeNode* root = new TreeNode(root_value); 18 | id++; 19 | root->left = helper(preorder, id, root_value); 20 | root->right = helper(preorder, id, limit); 21 | return root; 22 | } 23 | public: 24 | TreeNode* bstFromPreorder(vector& preorder) { 25 | int id = 0; 26 | return helper(preorder, id, INT_MAX); 27 | /* 28 | // O(N) space and time 29 | if(preorder.empty()) { 30 | return NULL; 31 | } 32 | int root_value = preorder[0]; 33 | TreeNode* root = new TreeNode(root_value); 34 | root->left = bstFromPreorder(preorder) 35 | vector smaller, greater; 36 | for(int i = 1; i < (int) preorder.size(); ++i) { 37 | if(preorder[i] < root_value) { 38 | smaller.push_back(preorder[i]); 39 | } 40 | else { 41 | greater.push_back(preorder[i]); 42 | } 43 | } 44 | cerr << root_value << " " << smaller.size() << " " << greater.size() << endl; 45 | root->left = bstFromPreorder(smaller); 46 | root->right = bstFromPreorder(greater); 47 | return root;*/ 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /AOC-2024/08.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | char a[1005][1005]; 4 | 5 | 6 | 7 | 8 | int main() { 9 | int H = -1; 10 | int W = -1; 11 | vector> where[256]; 12 | for (int row = 0; scanf(" %s", a[row]) != EOF; row++) { 13 | H = row + 1; 14 | W = strlen(a[row]); 15 | for (int col = 0; col < W; col++) { 16 | if (a[row][col] != '.') { 17 | where[(int)a[row][col]].emplace_back(row, col); 18 | } 19 | } 20 | } 21 | 22 | vector> yes(H, vector(W)); 23 | int answer = 0; 24 | for (int z = 0; z < 256; z++) { 25 | const vector>& v = where[z]; 26 | for (int i = 0; i < (int) v.size(); i++) { 27 | for (int j = 0; j < (int) v.size(); j++) { 28 | if (i == j) { 29 | continue; 30 | } 31 | int r = v[i].first; 32 | int c = v[i].second; 33 | int r2 = v[j].first; 34 | int c2 = v[j].second; 35 | int dx = r2 - r; 36 | int dy = c2 - c; 37 | int g = __gcd(dx, dy); 38 | dx /= g; 39 | dy /= g; 40 | for (int rep = 0; rep < 2; rep++) { 41 | for (int m = 0; true; m++) { 42 | int row = r + dx * m; 43 | int col = c + dy * m; 44 | if (0 <= row && row < H && 0 <= col && col < W) { 45 | if (!yes[row][col]) { 46 | yes[row][col] = true; 47 | answer++; 48 | } 49 | } 50 | else { 51 | break; 52 | } 53 | } 54 | dx *= -1; 55 | dy *= -1; 56 | } 57 | } 58 | } 59 | } 60 | cout << answer << "\n"; 61 | // for (int row = 0; row < H; row++) { 62 | // for (int col = 0; col < W; col++) { 63 | // if (yes[row][col]) { 64 | // cout << 1; 65 | // } 66 | // else { 67 | // cout << a[row][col]; 68 | // } 69 | // } 70 | // cout << "\n"; 71 | // } 72 | } 73 | -------------------------------------------------------------------------------- /leetcode/301-remove-invalid-parentheses.cpp: -------------------------------------------------------------------------------- 1 | 2 | vector pre; 3 | set,string>> visited; 4 | void rec(int i, int balance, string here, const string& s, vector& ret, int& best_len) { 5 | if(balance > pre[i]) { 6 | return; 7 | } 8 | pair,string> state{{i,balance},here}; 9 | if(!visited.insert(state).second) { 10 | return; 11 | } 12 | if(i == (int) s.length()) { 13 | if(balance != 0) { 14 | return; 15 | } 16 | if(here.length() > best_len) { 17 | ret.clear(); 18 | best_len = here.length(); 19 | ret.push_back(here); 20 | } 21 | else if(here.length() == best_len) { 22 | ret.push_back(here); 23 | } 24 | return; 25 | } 26 | if(s[i] == '(' || s[i] == ')') { 27 | rec(i + 1, balance, here, s, ret, best_len); 28 | } 29 | if(s[i] == '(') balance++; 30 | if(s[i] == ')') balance--; 31 | if(balance < 0) return; 32 | here += s[i]; 33 | rec(i + 1, balance, here, s, ret, best_len); 34 | } 35 | 36 | class Solution { 37 | public: 38 | vector removeInvalidParentheses(string s) { 39 | int n = s.length(); 40 | pre.clear(); 41 | pre.resize(n + 1); 42 | visited.clear(); 43 | for(int i = 0; i <= n; ++i) { 44 | for(int j = i; j < n; ++j) { 45 | if(s[j] == ')') { 46 | pre[i]++; 47 | } 48 | } 49 | } 50 | vector ret; 51 | int best_len = 0; 52 | rec(0, 0, "", s, ret, best_len); 53 | sort(ret.begin(), ret.end()); 54 | ret.resize( unique(ret.begin(), ret.end()) - ret.begin() ); 55 | return ret; 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /atcoder-dp/i.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | 35 | 36 | int main() { 37 | int n; 38 | scanf("%d", &n); 39 | // dp[heads] 40 | // if we had i tosses, then tails=i-heads 41 | vector dp(n + 1); 42 | // dp[i] - p-bility that there are i heads so far 43 | dp[0] = 1; 44 | for(int coin = 0; coin < n; ++coin) { 45 | double p_heads; 46 | scanf("%lf", &p_heads); 47 | for(int i = coin + 1; i >= 0; --i) { 48 | dp[i] = (i == 0 ? 0 : dp[i-1] * p_heads) + dp[i] * (1 - p_heads); 49 | } 50 | } 51 | double answer = 0; 52 | for(int heads = 0; heads <= n; ++heads) { 53 | int tails = n - heads; 54 | if(heads > tails) { 55 | answer += dp[heads]; 56 | } 57 | } 58 | printf("%.10lf\n", answer); 59 | } 60 | -------------------------------------------------------------------------------- /atcoder-dp/c.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | //~ const int INF = 1e9 + 5; 35 | 36 | int main() { 37 | int n; 38 | scanf("%d", &n); 39 | vector dp(3); 40 | // dp[i] - the total cost such that we did activity i on the last considered day 41 | for(int day = 0; day < n; ++day) { 42 | vector new_dp(3, 0); 43 | vector c(3); 44 | for(int i = 0; i < 3; ++i) { 45 | scanf("%d", &c[i]); 46 | } 47 | // int a, b, c - a lot of implementation 48 | for(int i = 0; i < 3; ++i) { 49 | for(int j = 0; j < 3; ++j) { 50 | if(i != j) { 51 | new_dp[j] = max(new_dp[j], dp[i] + c[j]); 52 | } 53 | } 54 | } 55 | dp = new_dp; 56 | } 57 | printf("%d\n", max({dp[0], dp[1], dp[2]})); 58 | } 59 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/15-product-of-array-except.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector productExceptSelf(vector& nums) { 4 | const int n = nums.size(); 5 | int product = 1; 6 | int count_zeros = 0; 7 | int product_of_non_zeros = 1; 8 | for(int x : nums) { 9 | product *= x; 10 | if(x == 0) { 11 | count_zeros++; 12 | } 13 | else { 14 | product_of_non_zeros *= x; 15 | } 16 | } 17 | vector answer(n); 18 | if(product != 0) { 19 | for(int i = 0; i < n; i++) { 20 | answer[i] = product / nums[i]; 21 | } 22 | } 23 | else if(count_zeros == 1) { 24 | for(int i = 0; i < n; i++) { 25 | if(nums[i] == 0) { 26 | answer[i] = product_of_non_zeros; 27 | } 28 | } 29 | } 30 | else { 31 | // do nothing 32 | } 33 | return answer; 34 | 35 | /* 36 | const int n = nums.size(); 37 | vector pref_product; 38 | pref_product.push_back(1); 39 | for(int x : nums) { 40 | pref_product.push_back(pref_product.back() * x); 41 | } 42 | //pref[0] = 1 43 | //pref[1] = a[0] 44 | //pref[2] = a[0] * a[1] 45 | //pref[i] == a[i-1] * ... * a[0] 46 | 47 | vector suf_product(n + 1); 48 | suf_product[n] = 1; 49 | for(int i = n - 1; i >= 0; --i) { 50 | suf_product[i] = suf_product[i+1] * nums[i]; 51 | } 52 | vector answer(n); 53 | for(int i = 0; i < n; i++) { 54 | answer[i] = pref_product[i] * suf_product[i+1]; 55 | } 56 | return answer;*/ 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /atcoder-dp/d.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | void max_self(ll& a, ll b) { 35 | a = max(a, b); 36 | } 37 | 38 | // O(n * W) 39 | 40 | int main() { 41 | int n, W; 42 | scanf("%d%d", &n, &W); 43 | vector dp(W + 1); // 0 ... W 44 | // dp[i] - the maximum total value of items with total weight exactly i 45 | for(int item = 0; item < n; ++item) { 46 | int weight, value; 47 | scanf("%d%d", &weight, &value); 48 | // dp[0] -> dp[3] -> dp[6] 49 | for(int weight_already = W - weight; weight_already >= 0; --weight_already) { 50 | //~ for(int weight_already = 0; weight_already <= W - weight; ++weight_already) { 51 | max_self(dp[weight_already+weight], dp[weight_already] + value); 52 | } 53 | } 54 | ll answer = 0; 55 | for(int i = 0; i <= W; ++i) { 56 | max_self(answer, dp[i]); 57 | } 58 | printf("%lld\n", answer); 59 | } 60 | -------------------------------------------------------------------------------- /matrix-exponentiation/h.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int nax = 5e5 + 5; 4 | const int mod = 1e9 + 7; 5 | char s[nax]; 6 | #define REP(i) for(int i = 0; i < 2; ++i) 7 | struct Matrix { 8 | int a[2][2] = {{0,0},{0,0}}; 9 | Matrix operator *(const Matrix& other) const { 10 | Matrix product; 11 | REP(i) REP(j) REP(k) { 12 | product.a[i][k] = (product.a[i][k] + (long long) a[i][j] * other.a[j][k]) % mod; 13 | } 14 | return product; 15 | } 16 | void init(char match) { 17 | REP(i) REP(j) { 18 | a[i][j] = 0; 19 | } 20 | for(char ch = 'A'; ch <= 'Z'; ++ch) { 21 | if(match == '?' || ch == match) { 22 | if(ch == 'H') { // everthing moves to happy 23 | a[0][1]++; 24 | a[1][1]++; 25 | } 26 | else if(ch == 'S' || ch == 'D') { 27 | a[0][0]++; 28 | a[1][0]++; 29 | } 30 | else if(ch == 'A' || ch == 'E' || ch == 'I' || ch == 'U' || ch == 'O') { 31 | a[0][1]++; 32 | a[1][0]++; 33 | } 34 | else { 35 | a[0][0]++; 36 | a[1][1]++; 37 | } 38 | } 39 | } 40 | } 41 | }; 42 | 43 | int main() { 44 | // H. String Mood Updates 45 | int n, q; 46 | scanf("%d%d", &n, &q); 47 | scanf("%s", s); 48 | 49 | int BASE = 1; 50 | while(BASE < n) { 51 | BASE *= 2; 52 | } 53 | vector tree(2 * BASE); 54 | for(int i = 0; i < n; ++i) { 55 | tree[BASE+i].init(s[i]); 56 | } 57 | for(int i = n; i < BASE; ++i) { 58 | tree[BASE+i].init('Z'); // neutral character 59 | } 60 | for(int i = BASE - 1; i >= 1; --i) { 61 | tree[i] = tree[2*i] * tree[2*i+1]; 62 | } 63 | printf("%d\n", tree[1].a[1][1]); // root.m[happy][happy] 64 | while(q--) { 65 | int i; 66 | char new_ch; 67 | scanf("%d %c", &i, &new_ch); 68 | i--; 69 | tree[BASE+i].init(new_ch); 70 | for(int x = (BASE + i) / 2; x >= 1; x /= 2) { 71 | tree[x] = tree[2*x] * tree[2*x+1]; 72 | } 73 | printf("%d\n", tree[1].a[1][1]); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /GCJ/2020/qual/C-parenting-prtntntn.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | 33 | 34 | void test_case() { 35 | int n; 36 | scanf("%d", &n); 37 | vector,int>> all; 38 | for(int i = 0; i < n; ++i) { 39 | int l, r; 40 | scanf("%d%d", &l, &r); 41 | all.emplace_back(make_pair(l, r), i); 42 | } 43 | sort(all.begin(), all.end()); 44 | string answer(n, '?'); 45 | int A = 0, B = 0; 46 | for(auto pp : all) { 47 | int low = pp.first.first; 48 | int high = pp.first.second; 49 | int id = pp.second; 50 | if(A <= low) { 51 | A = high; 52 | answer[id] = 'C';// += 'C'; 53 | } 54 | else if(B <= low) { 55 | B = high; 56 | answer[id] = 'J'; 57 | // answer += 'J'; 58 | } 59 | else { 60 | puts("IMPOSSIBLE"); 61 | return; 62 | } 63 | } 64 | printf("%s\n", answer.c_str()); 65 | } 66 | 67 | int main() { 68 | int T; 69 | scanf("%d", &T); 70 | for(int nr = 1; nr <= T; nr++) { 71 | printf("Case #%d: ", nr); 72 | test_case(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /POI/temperature/author.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * * 3 | * XVIII Olimpiada Informatyczna * 4 | * * 5 | * Zadanie: Temperatura * 6 | * Autor: Bartlomiej Wolowiec * 7 | * Zlozonosc czasowa: O(n) * 8 | * Opis: Rozwiazanie wzorcowe * 9 | * * 10 | *************************************************************************/ 11 | 12 | /* - */ 13 | #include 14 | #include 15 | #include 16 | #include 17 | #define PII pair 18 | using namespace std; 19 | /* * */ 20 | 21 | #define MAX_N 1000000 22 | int Tmin[MAX_N]; 23 | int Tmax[MAX_N]; 24 | 25 | 26 | #define TEMP second 27 | #define POZ first 28 | 29 | int main(void){ 30 | int n, wynik=0; 31 | 32 | if (scanf("%i", &n) != 1) return 1; 33 | for(int i=0; i Q; 37 | for(int i=0; i b){ 46 | wynik = max(wynik, i-Q.back().POZ); 47 | Q.pop_back(); 48 | } 49 | } 50 | while(!Q.empty()){ 51 | wynik = max(wynik, n-Q.back().POZ); 52 | Q.pop_back(); 53 | } 54 | printf("%i\n", wynik); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /leetcode/april-2020-challenge/21-leftmost-column-with-1.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * // This is the BinaryMatrix's API interface. 3 | * // You should not implement it, or speculate about its implementation 4 | * class BinaryMatrix { 5 | * public: 6 | * int get(int x, int y); 7 | * vector dimensions(); 8 | * }; 9 | */ 10 | 11 | //00000000111111111111111 12 | //???????1??????????????? 13 | 14 | // O(H+W) 15 | 16 | class Solution { 17 | public: 18 | int leftMostColumnWithOne(BinaryMatrix &binaryMatrix) { 19 | vector vec = binaryMatrix.dimensions(); 20 | int H = vec[0], W = vec[1]; 21 | int answer = W; 22 | for(int row = 0; row < H; ++row) { 23 | while(answer > 0 && binaryMatrix.get(row, answer - 1) == 1) { 24 | answer--; 25 | } 26 | } 27 | if(answer == W) { 28 | answer = -1; 29 | } 30 | return answer; 31 | /* 32 | vector order; 33 | for(int i = 0; i < H; ++i) { 34 | order.push_back(i); 35 | } 36 | random_shuffle(order.begin(), order.end()); 37 | for(int row : order) { 38 | if(answer == 0) { 39 | break; 40 | } 41 | int low = 0, high = answer - 1; 42 | // first one 43 | if(binaryMatrix.get(row, high) == 0) { 44 | continue; 45 | } 46 | // O(H + log(H) * log(W)) 47 | while(low <= high) { 48 | int mid = low + (high - low) / 2; 49 | if(binaryMatrix.get(row, mid) == 1) { 50 | answer = min(answer, mid); 51 | high = mid - 1; 52 | } 53 | else { 54 | low = mid + 1; 55 | } 56 | } 57 | } 58 | if(answer == W) { 59 | answer = -1; 60 | } 61 | return answer;*/ 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /atcoder-dp/x.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | struct S { 35 | int w, s, v; 36 | void read() { 37 | scanf("%d%d%d", &w, &s, &v); 38 | } 39 | bool operator <(const S& b) const { 40 | return w + s < b.w + b.s; 41 | } 42 | }; 43 | 44 | int main() { 45 | int n; 46 | scanf("%d", &n); 47 | vector in(n); 48 | int MAX_S = 20123; 49 | for(int i = 0; i < n; ++i) { 50 | in[i].read(); 51 | //~ MAX_S = max(MAX_S, in[i].s + in[i].w); 52 | } 53 | sort(in.begin(), in.end()); 54 | vector dp(MAX_S + 1); 55 | // dp[i] - best score of boxes with total weight i 56 | for(S block : in) { 57 | for(int w = min(block.s, MAX_S - block.w); w >= 0; --w) { 58 | dp[w+block.w] = max(dp[w+block.w], dp[w] + block.v); 59 | } 60 | } 61 | ll answer = 0; 62 | for(int i = 0; i <= MAX_S; ++i) { 63 | answer = max(answer, dp[i]); 64 | } 65 | printf("%lld\n", answer); 66 | } 67 | -------------------------------------------------------------------------------- /atcoder-dp/h.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | const int nax = 1005; 35 | char sl[nax][nax]; 36 | 37 | const int mod = 1e9 + 7; 38 | 39 | void add_self(int& a, int b) { 40 | a += b; 41 | if(a >= mod) { 42 | a -= mod; 43 | } 44 | } 45 | 46 | int main() { 47 | int h, w; 48 | scanf("%d%d", &h, &w); 49 | for(int row = 0; row < h; ++row) { 50 | scanf("%s", sl[row]); 51 | } 52 | vector> dp(h, vector(w)); 53 | dp[0][0] = 1; 54 | for(int row = 0; row < h; ++row) { 55 | for(int col = 0; col < w; ++col) { 56 | for(int r2 : {row, row + 1}) { 57 | int c2 = col; 58 | if(r2 == row) { 59 | c2 = col + 1; 60 | } 61 | if(r2 < h && c2 < w && sl[r2][c2] == '.') { 62 | add_self(dp[r2][c2], dp[row][col]); 63 | } 64 | } 65 | } 66 | } 67 | printf("%d\n", dp[h-1][w-1]); 68 | } 69 | -------------------------------------------------------------------------------- /GCJ/2020/qual/A-vestigium.cpp: -------------------------------------------------------------------------------- 1 | // GCJ Qual 2020 A. Vestigium https://codingcompetitions.withgoogle.com/codejam/round/000000000019fd27/000000000020993c 2 | // by Errichto 3 | #include 4 | using namespace std; 5 | #define sim template < class c 6 | #define ris return * this 7 | #define dor > debug & operator << 8 | #define eni(x) sim > typename \ 9 | enable_if(0) x 1, debug&>::type operator<<(c i) { 10 | sim > struct rge { c b, e; }; 11 | sim > rge range(c i, c j) { return rge{i, j}; } 12 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 13 | sim > char dud(...); 14 | struct debug { 15 | #ifdef LOCAL 16 | ~debug() { cerr << endl; } 17 | eni(!=) cerr << boolalpha << i; ris; } 18 | eni(==) ris << range(begin(i), end(i)); } 19 | sim, class b dor(pair < b, c > d) { 20 | ris << "(" << d.first << ", " << d.second << ")"; 21 | } 22 | sim dor(rge d) { 23 | *this << "["; 24 | for (auto it = d.b; it != d.e; ++it) 25 | *this << ", " + 2 * (it == d.b) << *it; 26 | ris << "]"; 27 | } 28 | #else 29 | sim dor(const c&) { ris; } 30 | #endif 31 | }; 32 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 33 | 34 | int grid[1005][1005]; 35 | 36 | void test_case() { 37 | int n; 38 | scanf("%d", &n); 39 | vector> row(n + 1), col(n + 1); 40 | long long trace = 0; 41 | for(int i = 1; i <= n; ++i) { 42 | for(int j = 1; j <= n; ++j) { 43 | scanf("%d", &grid[i][j]); 44 | row[i].insert(grid[i][j]); 45 | col[j].insert(grid[i][j]); 46 | if(i == j) { 47 | trace += grid[i][j]; 48 | } 49 | } 50 | } 51 | int bad_rows = 0, bad_cols = 0; 52 | for(int r = 1; r <= n; ++r) { 53 | if((int) row[r].size() != n) { 54 | ++bad_rows; 55 | } 56 | if((int) col[r].size() != n) { 57 | ++bad_cols; 58 | } 59 | } 60 | printf("%lld %d %d\n", trace, bad_rows, bad_cols); 61 | } 62 | 63 | int main() { 64 | int T; 65 | scanf("%d", &T); 66 | for(int nr = 1; nr <= T; nr++) { 67 | printf("Case #%d: ", nr); 68 | test_case(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /atcoder-dp/o.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | const int mod = 1e9 + 7; 35 | 36 | void add_self(int& a, int b) { 37 | a += b; 38 | if(a >= mod) { 39 | a -= mod; 40 | } 41 | } 42 | 43 | int main() { 44 | int n; 45 | scanf("%d", &n); 46 | vector> can(n, vector(n)); 47 | for(int i = 0; i < n; ++i) { 48 | for(int j = 0; j < n; ++j) { 49 | scanf("%d", &can[i][j]); 50 | } 51 | } 52 | vector dp(1 << n); // 2^n 53 | dp[0] = 1; 54 | //~ for(int a = 0; a < n; ++a) { 55 | for(int mask = 0; mask < (1 << n) - 1; ++mask) { 56 | int a = __builtin_popcount(mask); // the number of bits set to 1 57 | for(int b = 0; b < n; ++b) { 58 | if(can[a][b] && !(mask & (1 << b))) { 59 | int m2 = mask ^ (1 << b); 60 | //~ debug() << imie(mask) imie(m2) imie(dp[mask]); 61 | add_self(dp[m2], dp[mask]); 62 | } 63 | } 64 | } 65 | //~ } 66 | printf("%d\n", dp[(1< debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | // DAG - directed acyclic graph 35 | 36 | const int nax = 1e5 + 5; 37 | vector edges[nax]; 38 | int in_degree[nax]; // the number of edges going to 'b' 39 | int dist[nax]; 40 | bool visited[nax]; 41 | 42 | void dfs(int a) { 43 | assert(!visited[a]); 44 | visited[a] = true; 45 | for(int b : edges[a]) { 46 | dist[b] = max(dist[b], dist[a] + 1); 47 | --in_degree[b]; 48 | if(in_degree[b] == 0) { 49 | dfs(b); 50 | } 51 | } 52 | } 53 | 54 | int main() { 55 | int n, m; 56 | scanf("%d%d", &n, &m); 57 | while(m--) { 58 | int a, b; 59 | scanf("%d%d", &a, &b); 60 | edges[a].push_back(b); 61 | ++in_degree[b]; 62 | } 63 | for(int i = 1; i <= n; ++i) { 64 | if(!visited[i] && in_degree[i] == 0) { 65 | dfs(i); 66 | } 67 | } 68 | int answer = 0; 69 | for(int i = 1; i <= n; ++i) { 70 | answer = max(answer, dist[i]); 71 | } 72 | printf("%d\n", answer); 73 | } 74 | -------------------------------------------------------------------------------- /atcoder-dp/n.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | const int nax = 405; 35 | const ll INF = 1e18L + 5; // 10^18+5 36 | ll dp[nax][nax]; 37 | // dp[i][j] - the minimum total cost of combining interval [i,j] into one vertex 38 | 39 | int main() { 40 | int n; 41 | scanf("%d", &n); 42 | vector a(n); 43 | for(int& x : a) { 44 | scanf("%d", &x); 45 | } 46 | auto sum = [&](int L, int R) { 47 | ll s = 0; 48 | for(int i = L; i <= R; ++i) { 49 | s += a[i]; 50 | } 51 | return s; 52 | }; 53 | for(int L = n - 1; L >= 0; --L) { 54 | for(int R = L; R < n; ++R) { 55 | if(L == R) { 56 | dp[L][R] = 0; 57 | } 58 | else { 59 | dp[L][R] = INF; 60 | ll s = sum(L, R); 61 | for(int i = L; i <= R - 1; ++i) { 62 | dp[L][R] = min(dp[L][R], dp[L][i] + dp[i+1][R] + s); 63 | } 64 | } 65 | } 66 | } 67 | 68 | printf("%lld\n", dp[0][n-1]); 69 | } 70 | -------------------------------------------------------------------------------- /AOC-2024/20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int NAX = 142; 5 | char a[NAX][NAX]; 6 | int H, W; 7 | const int INF = 1e9 + 5; 8 | vector> dirs{{-1,0},{0,1},{1,0},{0,-1}}; 9 | 10 | bool inside(int row, int col) { 11 | return 0 <= row && row < H && 0 <= col && col < W; 12 | } 13 | 14 | vector> bfs(pair start) { 15 | vector> d(H, vector(W, INF)); 16 | d[start.first][start.second] = 0; 17 | vector> q; 18 | q.push_back(start); 19 | for (int z = 0; z < (int) q.size(); z++) { 20 | int r = q[z].first; 21 | int c = q[z].second; 22 | if (a[r][c] == '#') { 23 | continue; 24 | } 25 | for (pair dir : dirs) { 26 | int r2 = r + dir.first; 27 | int c2 = c + dir.second; 28 | if (inside(r2, c2) && d[r2][c2] == INF) { 29 | d[r2][c2] = d[r][c] + 1; 30 | q.emplace_back(r2, c2); 31 | } 32 | } 33 | } 34 | return d; 35 | } 36 | 37 | int main() { 38 | for (int row = 0; scanf("%s", a[row]) != EOF; row++) { 39 | H = row + 1; 40 | W = strlen(a[row]); 41 | } 42 | pair start, end; 43 | for (int row = 0; row < H; row++) { 44 | for (int col = 0; col < W; col++) { 45 | printf("%c%c", a[row][col], a[row][col]); 46 | if (a[row][col] == 'S') { 47 | start = {row, col}; 48 | a[row][col] = '.'; 49 | } 50 | if (a[row][col] == 'E') { 51 | end = {row, col}; 52 | a[row][col] = '.'; 53 | } 54 | } 55 | puts(""); 56 | } 57 | 58 | vector> A = bfs(start), B = bfs(end); 59 | 60 | int normal = A[end.first][end.second]; 61 | int answer = 0; 62 | for (int r = 0; r < H; r++) { 63 | for (int c = 0; c < W; c++) { 64 | if (a[r][c] == '#') { 65 | for (auto [dr,dc] : dirs) { 66 | // for (pair dir : dirs) { 67 | int r2 = r + dr; 68 | int c2 = c + dc; 69 | if (inside(r2, c2) && a[r2][c2] != '#') { 70 | int here = A[r][c] + B[r2][c2] + 1; 71 | if (here <= normal - 100) { 72 | answer++; 73 | } 74 | } 75 | } 76 | } 77 | } 78 | } 79 | printf("%d\n", answer); 80 | } 81 | -------------------------------------------------------------------------------- /AOC-2024/15.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | char a[105][105]; 5 | 6 | // <<^^<>>^v^v 7 | pair getDir(char c) { 8 | if (c == '^') return {-1, 0}; 9 | if (c == 'v') return {1, 0}; 10 | if (c == '>') return {0, 1}; 11 | if (c == '<') return {0, -1}; 12 | assert(false); 13 | } 14 | 15 | int main() { 16 | int H, W; 17 | string moves; 18 | for (int row = 0; true; row++) { 19 | scanf("%s", a[row]); 20 | W = strlen(a[row]); 21 | if (W == 0 || W == 1 || (row >= 1 && W != (int) strlen(a[row-1]))) { 22 | H = row; 23 | W = strlen(a[row-1]); 24 | moves += string(a[row]); 25 | while (scanf("%s", a[row]) != EOF) { 26 | moves += string(a[row]); 27 | } 28 | break; 29 | } 30 | } 31 | // printf("%d %d\n", H, W); 32 | // printf("%d\n", (int) moves.length()); 33 | pair me{-1,-1}; // row, column 34 | for (int row = 0; row < H; row++) { 35 | for (int col = 0; col < W; col++) { 36 | if (a[row][col] == '@') { 37 | me = {row, col}; 38 | a[row][col] = '.'; 39 | } 40 | } 41 | } 42 | assert(me.first != -1); 43 | for (char move : moves) { 44 | pair dir = getDir(move); 45 | vector> boxes; 46 | int row = me.first; 47 | int col = me.second; 48 | bool emptySpace = false; 49 | while (true) { 50 | row += dir.first; 51 | col += dir.second; 52 | if (a[row][col] == '#') { 53 | break; 54 | } 55 | if (a[row][col] == '.') { 56 | emptySpace = true; 57 | break; 58 | } 59 | assert(a[row][col] == 'O'); 60 | boxes.emplace_back(row, col); 61 | } 62 | if (!emptySpace) { 63 | continue; 64 | } 65 | me.first += dir.first; 66 | me.second += dir.second; 67 | for (pair p : boxes) { 68 | a[p.first][p.second] = '.'; 69 | } 70 | for (pair p : boxes) { 71 | a[p.first+dir.first][p.second+dir.second] = 'O'; 72 | } 73 | } 74 | int answer = 0; 75 | for (int row = 0; row < H; row++) { 76 | for (int col = 0; col < W; col++) { 77 | if (a[row][col] == 'O') { 78 | answer += 100 * row + col; 79 | } 80 | } 81 | } 82 | printf("%d\n", answer); 83 | } 84 | -------------------------------------------------------------------------------- /PSUT-coding-marathon/d.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | // (2 4) (5 7) (7 6) (3 1) 35 | 36 | // (5 9) (7 20) 37 | 38 | int main() { 39 | int n; 40 | scanf("%d", &n); 41 | n /= 2; 42 | vector> a; 43 | for(int i = 0; i < n; ++i) { 44 | int x, y; 45 | scanf("%d%d", &x, &y); 46 | if(x > y) { 47 | swap(x, y); 48 | } 49 | a.emplace_back(x, y); 50 | } 51 | sort(a.begin(), a.end()); 52 | vector> one, two; 53 | // one: (2, 4), (5, 7) 54 | // two: (3, 6) 55 | // 56 | for(pair interval : a) { 57 | if(one.empty() || one.back().second <= interval.first) { 58 | one.push_back(interval); 59 | } 60 | else if(two.empty() || two.back().second <= interval.first) { 61 | two.push_back(interval); 62 | } 63 | else { 64 | puts("-1"); 65 | return 0; 66 | } 67 | } 68 | for(pair interval : one) { 69 | printf("%d %d ", interval.first, interval.second); 70 | } 71 | reverse(two.begin(), two.end()); 72 | for(pair interval : two) { 73 | printf("%d %d ", interval.second, interval.first); 74 | } 75 | puts(""); 76 | } 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /AOC-2024/16.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | char a[505][505]; 4 | 5 | vector> dirs = {{0,1},{-1,0},{0,-1},{1,0}}; 6 | 7 | struct State { 8 | int row, col, dir; 9 | bool operator <(const State& he) const { 10 | return make_pair(row, make_pair(col, dir)) < make_pair(he.row, make_pair(he.col, he.dir)); 11 | } 12 | }; 13 | 14 | int main() { 15 | // 'S' and 'E' 16 | int H, W; 17 | pair start, target; 18 | for (int row = 0; scanf("%s", a[row]) != EOF; row++) { 19 | H = row + 1; 20 | W = strlen(a[row]); 21 | for (int col = 0; col < W; col++) { 22 | if (a[row][col] == 'S') { 23 | a[row][col] = '.'; 24 | start = {row, col}; 25 | } 26 | if (a[row][col] == 'E') { 27 | a[row][col] = '.'; 28 | target = {row, col}; 29 | } 30 | } 31 | } 32 | // Dijkstra 33 | set> s; 34 | map dist; 35 | State starting_state{start.first, start.second, 0}; 36 | dist[starting_state] = 0; 37 | s.insert(make_pair(0, starting_state)); 38 | while (!s.empty()) { 39 | State state = s.begin()->second; 40 | s.erase(s.begin()); 41 | // printf("%d %d %d %d\n", state.row, state.col, state.dir, maybe); 42 | for (int i = 0; i < 3; i++) { 43 | int maybe = dist[state]; 44 | State s2 = state; 45 | if (i == 0) { 46 | s2.row += dirs[s2.dir].first; 47 | s2.col += dirs[s2.dir].second; 48 | if (a[s2.row][s2.col] == '#') { 49 | continue; 50 | } 51 | if (!(0 <= s2.row && s2.row < H && 0 <= s2.col && s2.col < W)) { 52 | assert(false); 53 | } 54 | maybe++; 55 | } 56 | else if (i == 1) { 57 | s2.dir = (s2.dir + 1) % 4; 58 | maybe += 1000; 59 | } 60 | else { 61 | s2.dir = (s2.dir + 3) % 4; 62 | maybe += 1000; 63 | } 64 | if (!dist.count(s2) || dist[s2] > maybe) { 65 | if (dist.count(s2)) { 66 | s.erase(make_pair(dist[s2], s2)); 67 | } 68 | dist[s2] = maybe; 69 | s.insert(make_pair(maybe, s2)); 70 | } 71 | } 72 | } 73 | int ans = INT_MAX; 74 | for (int i = 0; i < 4; i++) { 75 | State t{target.first, target.second, i}; 76 | if (dist.count(t)) { 77 | ans = min(ans, dist[t]); 78 | } 79 | } 80 | printf("%d\n", ans); 81 | } 82 | -------------------------------------------------------------------------------- /AOC-2024/05-part2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | map> edges; 5 | 6 | 7 | 8 | void topo(int a, vector& order, map& in, const set& present) { 9 | order.push_back(a); 10 | for (int b : edges[a]) { 11 | if (present.count(b)) { 12 | if (--in[b] == 0) { 13 | topo(b, order, in, present); 14 | } 15 | } 16 | } 17 | } 18 | 19 | int main() { 20 | string s; 21 | long long answer = 0; 22 | while (getline(cin, s)) { 23 | if (s.empty() || !isdigit(s[0])) { 24 | continue; 25 | } 26 | int len = (int) s.length(); 27 | // cout << s << "\n"; 28 | vector v; 29 | bool was_pipe = false; 30 | for (int i = 0; i < len; i++) { 31 | if (isdigit(s[i])) { 32 | int x = 0; 33 | while (isdigit(s[i])) { 34 | x = 10 * x + (s[i] - '0'); 35 | i++; 36 | } 37 | v.push_back(x); 38 | // cout << "i=" << i << " s[i]=" << int(s[i]) << "\n"; 39 | if (s[i] == '|') { 40 | was_pipe = true; 41 | } 42 | assert(s[i] == ',' || s[i] == '|' || s[i] == '\n' || s[i] == 0); 43 | // cout << "x=" << x << " "; 44 | } 45 | } 46 | if (was_pipe) { 47 | edges[v[0]].push_back(v[1]); 48 | } 49 | else { 50 | 51 | set earlier; 52 | bool ok = true; 53 | // O(Q * K * OUT_DEGREE * log) 54 | // O(Q * K^2 * log) -- if you iterated pairs (x,y) in the input 55 | map in; 56 | set present; 57 | for (int x : v) { 58 | present.insert(x); 59 | } 60 | for (int i = 0; i < (int) v.size(); i++) { 61 | int x = v[i]; 62 | for (int y : edges[x]) { 63 | if (present.count(y)) { 64 | ++in[y]; 65 | } 66 | if (earlier.count(y)) { 67 | ok = false; 68 | } 69 | } 70 | earlier.insert(x); 71 | } 72 | if (ok) { 73 | // answer += v[v.size()/2]; 74 | } 75 | else { 76 | // incorrect 77 | vector order; 78 | vector starting; 79 | for (int x : v) { 80 | if (in[x] == 0) { 81 | starting.push_back(x); 82 | } 83 | } 84 | for (int x : starting) { 85 | topo(x, order, in, present); 86 | } 87 | answer += order[order.size()/2]; 88 | } 89 | } 90 | } 91 | cout << answer << "\n"; 92 | } 93 | -------------------------------------------------------------------------------- /atcoder-dp/e.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | void max_self(ll& a, ll b) { 35 | a = max(a, b); 36 | } 37 | void min_self(ll& a, ll b) { 38 | a = min(a, b); 39 | } 40 | 41 | const ll INF = 1e18L + 5; 42 | 43 | int main() { 44 | int n, W; 45 | scanf("%d%d", &n, &W); 46 | vector weight(n), value(n); 47 | for(int i = 0; i < n; ++i) { 48 | scanf("%d%d", &weight[i], &value[i]); 49 | } 50 | int sum_value = 0; 51 | for(int x : value) { 52 | sum_value += x; 53 | } 54 | vector dp(sum_value + 1, INF); // 0 ... W 55 | dp[0] = 0; 56 | // dp[i] - the minimum total weight of items with total value exactly i 57 | for(int item = 0; item < n; ++item) { 58 | for(int value_already = sum_value - value[item]; value_already >= 0; --value_already) { 59 | //~ for(int weight_already = 0; weight_already <= W - weight; ++weight_already) { 60 | min_self(dp[value_already+value[item]], dp[value_already] + weight[item]); 61 | } 62 | } 63 | ll answer = 0; 64 | for(int i = 0; i <= sum_value; ++i) { 65 | if(dp[i] <= W) { 66 | answer = max(answer, (ll) i); 67 | } 68 | //~ min_self(answer, dp[i]); 69 | } 70 | printf("%lld\n", answer); 71 | } 72 | -------------------------------------------------------------------------------- /PSUT-coding-marathon/e.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | // you get to the same cell only if L=R and U=D 35 | 36 | const int MAX_N = 1e6 + 5; 37 | char a[MAX_N]; 38 | 39 | int main() { 40 | // LRRRLRLLRLLLLL 41 | // 0, -1, 0, 1, 2, ... 42 | int n; 43 | scanf("%d", &n); 44 | scanf("%s", a); 45 | assert(n == (int) strlen(a)); 46 | vector> pref; 47 | int x = 0, y = 0; 48 | pref.emplace_back(x, y); 49 | for(int i = 0; i < n; ++i) { 50 | if(a[i] == 'L') { 51 | x--; 52 | } 53 | else if(a[i] == 'R') { 54 | x++; 55 | } 56 | else if(a[i] == 'U') { 57 | y++; 58 | } 59 | else if(a[i] == 'D') { 60 | y--; 61 | } 62 | else { 63 | assert(false); // unknown character 64 | } 65 | pref.emplace_back(x, y); 66 | } 67 | 68 | // two pointers / caterpillar 69 | 70 | // _ S _ _ _ E 71 | 72 | debug() << imie(pref); 73 | 74 | int start = 0; 75 | int answer = 0; 76 | set> in_substring; 77 | for(int end = 0; end < (int) pref.size(); ++end) { 78 | // pref[end] is the last position visited 79 | while(in_substring.count(pref[end])) { 80 | in_substring.erase(pref[start]); 81 | start++; 82 | } 83 | in_substring.insert(pref[end]); 84 | answer = max(answer, end - start); 85 | } 86 | printf("%d\n", answer); 87 | } 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /atcoder-dp/p.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | const int nax = 1e5 + 5; 35 | vector edges[nax]; 36 | 37 | const int mod = 1e9 + 7; 38 | int mul(int a, int b) { 39 | return (ll) a * b % mod; 40 | } 41 | 42 | // returns a pair {black, white} 43 | pair dfs(int a, int parent) { 44 | int all_white = 1; // means: my vertex can be painted black 45 | int sth_is_black = 0; 46 | for(int b : edges[a]) { 47 | if(b != parent) { 48 | pair p = dfs(b, a); 49 | // p.first is the number of ways to color the subtree 50 | // such that 'b' is black 51 | int memo_all_white = all_white; 52 | all_white = mul(all_white, p.second); 53 | sth_is_black = (mul(memo_all_white, p.first) 54 | + mul(sth_is_black, p.first + p.second)) % mod; 55 | } 56 | } 57 | return make_pair(all_white, (all_white + sth_is_black) % mod); 58 | } 59 | 60 | int main() { 61 | int n; 62 | scanf("%d", &n); 63 | for(int i = 0; i < n - 1; ++i) { 64 | int a, b; 65 | scanf("%d%d", &a, &b); 66 | edges[a].push_back(b); 67 | edges[b].push_back(a); 68 | } 69 | pair p = dfs(1, -1); 70 | int answer = (p.first + p.second) % mod; 71 | printf("%d\n", answer); 72 | } 73 | -------------------------------------------------------------------------------- /atcoder-dp/m.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | using namespace std; 3 | #define sim template < class c 4 | #define ris return * this 5 | #define dor > debug & operator << 6 | #define eni(x) sim > typename \ 7 | enable_if(0) x 1, debug&>::type operator<<(c i) { 8 | sim > struct rge { c b, e; }; 9 | sim > rge range(c i, c j) { return rge{i, j}; } 10 | sim > auto dud(c* x) -> decltype(cerr << *x, 0); 11 | sim > char dud(...); 12 | struct debug { 13 | #ifdef LOCAL 14 | ~debug() { cerr << endl; } 15 | eni(!=) cerr << boolalpha << i; ris; } 16 | eni(==) ris << range(begin(i), end(i)); } 17 | sim, class b dor(pair < b, c > d) { 18 | ris << "(" << d.first << ", " << d.second << ")"; 19 | } 20 | sim dor(rge d) { 21 | *this << "["; 22 | for (auto it = d.b; it != d.e; ++it) 23 | *this << ", " + 2 * (it == d.b) << *it; 24 | ris << "]"; 25 | } 26 | #else 27 | sim dor(const c&) { ris; } 28 | #endif 29 | }; 30 | #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " 31 | 32 | using ll = long long; 33 | 34 | const int mod = 1e9 + 7; 35 | 36 | // O(N * K^2) 37 | 38 | void add_self(int& a, int b) { 39 | a += b; 40 | if(a >= mod) { 41 | a -= mod; 42 | } 43 | } 44 | void sub_self(int& a, int b) { 45 | a -= b; 46 | if(a < 0) { 47 | a += mod; 48 | } 49 | } 50 | 51 | int main() { 52 | int n, k; 53 | scanf("%d%d", &n, &k); 54 | vector dp(k + 1); 55 | // dp[i] - the number of ways such that we used i candies so far 56 | dp[0] = 1; 57 | for(int child = 0; child < n; ++child) { 58 | int up_to; 59 | scanf("%d", &up_to); 60 | vector fake(k + 1); 61 | for(int used = k; used >= 0; --used) { 62 | int tmp = dp[used]; 63 | int L = used + 1; 64 | int R = used + min(up_to, k - used); 65 | if(L <= R) { 66 | add_self(fake[L], tmp); 67 | if(R + 1 <= k) { 68 | sub_self(fake[R+1], tmp); 69 | } 70 | } 71 | //~ for(int i = L; i <= R; ++i) { 72 | //~ add_self(dp[i], tmp); 73 | //~ } 74 | } 75 | int prefix_sum = 0; 76 | for(int i = 0; i <= k; ++i) { 77 | add_self(prefix_sum, fake[i]); 78 | add_self(dp[i], prefix_sum); 79 | } 80 | } 81 | printf("%d\n", dp[k]); 82 | } 83 | --------------------------------------------------------------------------------