<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Tenzly</title><description>Personal Site</description><link>https://tenzly-amirzaky.vercel.app/</link><language>en</language><item><title>Aplikasi Chatting via Scoket</title><link>https://tenzly-amirzaky.vercel.app/posts/chatting-socket/</link><guid isPermaLink="true">https://tenzly-amirzaky.vercel.app/posts/chatting-socket/</guid><description>membuat Aplikasi Chatting berbasis Python Socket</description><pubDate>Sat, 11 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;🧵 Simple Python Chat App (Socket + Threading + Prompt Toolkit)&lt;/h1&gt;
&lt;p&gt;Aplikasi ini adalah contoh sederhana &lt;strong&gt;chat server &amp;amp; client berbasis Socket&lt;/strong&gt; menggunakan Python.
Server dapat menerima banyak client sekaligus dengan bantuan &lt;strong&gt;threading&lt;/strong&gt;, dan tampilan client lebih nyaman menggunakan &lt;strong&gt;prompt_toolkit&lt;/strong&gt; sehingga input pesan tidak terganggu oleh pesan masuk.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;📁 Struktur Project&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;chat-app/
│── server.py
│── client.py
│── README.md   (file ini)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;⚙️ Fitur&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Multi-user chat dalam satu jaringan&lt;/li&gt;
&lt;li&gt;Broadcast pesan ke semua client&lt;/li&gt;
&lt;li&gt;Notifikasi user join/leave&lt;/li&gt;
&lt;li&gt;Input client rapi berkat &lt;strong&gt;prompt_toolkit&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Thread-safe dictionary untuk list client&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;🖥️ server.py&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import socket
import threading

HOST = &quot;0.0.0.0&quot;  # Listen pada semua interface LAN/WiFi
PORT = 12345

clients = {}  # {socket: name}
lock = threading.Lock()  # untuk akses thread-safe ke clients

def broadcast(msg, sender=None):
    with lock:
        for client in list(clients):
            if client != sender:
                try:
                    client.sendall(msg.encode(&apos;utf-8&apos;))
                except (ConnectionResetError, OSError):
                    client.close()
                    del clients[client]

def handle_client(client_socket, addr):
    try:
        name = client_socket.recv(1024).decode(&apos;utf-8&apos;)
        with lock:
            clients[client_socket] = name
        broadcast(f&quot;{name} has joined the chat!&quot;, sender=client_socket)

        while True:
            msg = client_socket.recv(1024).decode(&apos;utf-8&apos;)
            if not msg:
                break
            broadcast(f&quot;{name}: {msg}&quot;, sender=client_socket)

    except (ConnectionResetError, OSError):
        pass
    finally:
        with lock:
            if client_socket in clients:
                name = clients[client_socket]
                del clients[client_socket]
                broadcast(f&quot;{name} has left the chat.&quot;)
        client_socket.close()

def start():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((HOST, PORT))
    server.listen()
    print(f&quot;Server running on {HOST}:{PORT}&quot;)

    try:
        while True:
            client_socket, addr = server.accept()
            threading.Thread(target=handle_client, args=(client_socket, addr), daemon=True).start()
    except KeyboardInterrupt:
        print(&quot;\nServer shutting down...&quot;)
        with lock:
            for client in list(clients):
                client.close()
        server.close()

if __name__ == &quot;__main__&quot;:
    start()
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;🧑‍💻 client.py&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import socket
import threading
from prompt_toolkit import PromptSession
from prompt_toolkit.patch_stdout import patch_stdout

SERVER_IP = &quot;127.0.0.1&quot;  # Sesuaikan dengan IP server LAN
PORT = 12345

def receive_messages(sock):
    while True:
        try:
            msg = sock.recv(1024).decode()
            if msg:
                with patch_stdout():
                    print(msg)  # tampil di atas prompt tanpa merusak input
        except:
            print(&quot;Disconnected from server&quot;)
            sock.close()
            break

def main():
    name = input(&quot;Enter your name: &quot;)

    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect((SERVER_IP, PORT))
    client.sendall(name.encode())
    print(f&quot;Connected to chat server as {name}!&quot;)

    session = PromptSession()
    threading.Thread(target=receive_messages, args=(client,), daemon=True).start()

    while True:
        msg = session.prompt(&quot;You: &quot;)
        if msg.lower() == &quot;&amp;lt;exit&amp;gt;&quot;:
            client.close()
            break
        client.sendall(msg.encode())

if __name__ == &quot;__main__&quot;:
    main()
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;📡 Cara Menjalankan&lt;/h2&gt;
&lt;h3&gt;1️⃣ Install dependency&lt;/h3&gt;
&lt;p&gt;Client membutuhkan &lt;strong&gt;prompt_toolkit&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install prompt_toolkit
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2️⃣ Jalankan Server&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;python server.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Server akan listen di:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0.0.0.0:12345
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3️⃣ Jalankan Client&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;python client.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sebelum connect, ubah bagian berikut pada &lt;code&gt;client.py&lt;/code&gt; agar sesuai IP server LAN:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SERVER_IP = &quot;192.168.x.x&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;📝 Catatan&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Jika client ingin disconnect, ketik:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;exit&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Semua pesan otomatis di-broadcast ke user lain.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;📦 Lisensi&lt;/h2&gt;
&lt;p&gt;Proyek ini bebas digunakan untuk belajar atau dikembangkan lagi.&lt;br /&gt;
Tambahkan fitur seperti GUI, enkripsi pesan, atau user list jika diperlukan!&lt;/p&gt;
</content:encoded></item><item><title>Cheatsheet CP</title><link>https://tenzly-amirzaky.vercel.app/posts/cheatsheet_cp/</link><guid isPermaLink="true">https://tenzly-amirzaky.vercel.app/posts/cheatsheet_cp/</guid><description>Cheatsheet Untuk Competitiv Programming (HaveFun++)</description><pubDate>Sat, 11 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;strong&gt;I N T R O&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Ini tempat kita nge-drop semua Competitive Programming cheatsheets. Cheatsheet bisa berubah sewaktu-waktu, jadi pastikan cek update terbaru kalau mau pakai. Feel free ambil sesuai kebutuhan, tapi please jangan lupa kasih credit ke HaveFun++ supaya supaya ga di marahin Pak Tz (jokes hahaa:&amp;lt;3).&lt;/p&gt;
&lt;p&gt;Think of this as a shared toolbox—ambil yang perlu, pakai sebaiknya, dan kalau bisa, contribute juga kalau punya update atau improvement.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;cp-algorithms.com&quot;&gt;CP-ALgorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/cp-algorithms/cp-algorithms&quot;&gt;CP-ALgorithm &lt;strong&gt;Github&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1rQcyJf_X5VC8_xlnQRyQHx_fWEiqj-qf/view&quot;&gt;Cheatsheet &lt;strong&gt;Addon&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2&gt;&lt;strong&gt;D A F T A R   I S I&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;HaveFun++ Competitive Programming Cheatsheet
│
├── 1. Math &amp;amp; Number Theory
│ ├── 1.1. GCD, LCM, dan Extended Euclid (Mod Inverse General)
│ ├── 1.2. Primes &amp;amp; Sieve of Eratosthenes
│ ├── 1.3. Modular Arithmetic &amp;amp; Fast Exponentiation (Pow Mod)
│ ├── 1.4. Modular Inverse (Fermat &amp;amp; Ext. Euclid)
│ ├── 1.5. Euler&apos;s Totient Function (Phi)
│ ├── 1.6. Combinatorics &amp;amp; Special Sequences
│ │ ├── 1.6.1. Factorials &amp;amp; nCr (Precompute O(1) Query)
│ │ ├── 1.6.2. Lucas Theorem (n Besar, Mod Kecil Prime)
│ │ └── 1.6.3. Catalan &amp;amp; Fibonacci (Fast Doubling)
│ └── 1.7. Chinese Remainder Theorem (note)
│
├── 2. Algoritma Dasar (Brute Force, Greedy, Window, Pointer)
│ ├── 2.1. Brute Force (Tips: Pruning, Bitmask)
│ ├── 2.2. Greedy (Pattern Checklist &amp;amp; Pitfalls)
│ ├── 2.3. Two Pointers (Typical Problems &amp;amp; Templates)
│ └── 2.4. Sliding Window (Fixed &amp;amp; Variable Patterns)
│
├── 3. Dynamic Programming
│ ├── 3.1. Knapsack (0/1, Unbounded)
│ └── 3.2. DP Tips (State, Transition, Memory)
│
├── 4. Graf (Graph)
│ ├── 4.1. BFS / DFS (Connectivity, Unweighted Shortest Path)
│ ├── 4.2. Shortest Paths (Dijkstra, Bellman-Ford)
│ ├── 4.3. Minimum Spanning Tree (Kruskal, Prim)
│ ├── 4.4. Directed Graphs (Topological Sort, DP on DAG)
│ ├── 4.5. Strong/Biconnected (SCC Kosaraju, Bridges/AP Tarjan)
│ ├── 4.6. Max Flow (Dinic) &amp;amp; Bipartite Matching
│ └── 4.7. Tree Queries (LCA Binary Lifting, Diameter)
│
├── 5. Classic Puzzles / Links
│ ├── 5.1. Non-Crossing Handshakes (Catalan)
│ └── 5.2. The Water Jug Problem (BFS on States / GCD)
│
└── 6. Snippets &amp;amp; Templates
├── 6.1. Fast I/O &amp;amp; Macros (e.g. __int128)
│
├── 7. Graphs
│ ├── 7.1. BFS / DFS
│ ├── 7.2. Shortest paths (Dijkstra)
│ └── 7.3. All-pairs (Floyd-Warshall) &amp;amp; MST note
│
├── 8. Classic Puzzles / Links
│ ├── 8.1. Number of Ways to Handshakes That Don&apos;t Cross - GeeksforGeeks
│ │ (link: https://share.google/3gpDL8D2vs6LWh3NP)
│ └── 8.2. The Water Jug Problem - Count Min Steps - GeeksforGeeks
│ (link: https://share.google/I8Buc1xX6cC8SYjfd)
│
└── 9. Snippets &amp;amp; Templates
├── 9.1. Fast I/O
├── 9.2. Useful macros / helpers
└── 9.3. Contribution note &amp;amp; credits
│
└── 99. ontoh Problem
├── 99.1. Jumlah dari Jumlah
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;strong&gt;C H E A T  -  S h e e t&lt;/strong&gt;&lt;/h2&gt;
&lt;h2&gt;1. MATH (fundamental)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Letakkan math di depan karena sering dipakai dan bikin solusi jadi elegan.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.1 GCD / LCM&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;GCD (Euclidean):&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
long long gcd(long long a, long long b) {
    while (b) { long long t = b; b = a % b; a = t; }
    return a;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LCM: lcm(a,b) = a / gcd(a,b) * b (hati-hati overflow)&lt;/p&gt;
&lt;h3&gt;1.2 Extended Euclid (modular inverse for non-prime mod)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;long long extgcd(long long a, long long b, long long &amp;amp;x, long long &amp;amp;y) {
    if (b==0) { x=1; y=0; return a; }
    long long x1,y1;
    long long g = extgcd(b, a%b, x1, y1);
    x = y1;
    y = x1 - (a/b) * y1;
    return g;
}
// inverse exists if gcd(a,mod)=1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.3 Fast exponentiation (mod)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;long long modpow(long long a, long long e, long long mod) {
    long long r=1; a%=mod;
    while (e) {
        if (e&amp;amp;1) r = (__int128)r*a%mod;
        a = (__int128)a*a%mod;
        e &amp;gt;&amp;gt;= 1;
    }
    return r;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.4 Modular inverse (prime mod)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If mod is prime: inv(a) = a^{mod-2} mod mod (use modpow).&lt;/li&gt;
&lt;li&gt;If not prime: use extended gcd.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.5 Primes &amp;amp; Sieve of Eratosthenes (O(n log log n))&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#define ll long long
vector&amp;lt;ll&amp;gt;v;
void Sieve(ll n) {
	vector&amp;lt;bool&amp;gt; prima(n + 1, true);
	prima[1] = prima[0] = false;
	for (ll j = 4; j &amp;lt;= n; j += 2) {
		prima[j] = false;
	}
	for (ll i = 3; i * i &amp;lt;= n; i += 2) {
		if (prima[i] == true) {
			for (ll j = i * i; j &amp;lt;= n; j += i) {
				prima[j] = false;
			}
		}
	}
	int count{1};
	v.push_back(2 - 1);

	for (ll i = 3; i &amp;lt;= n; i++) {
		if (prima[i] == true) {
			ll temp = (i - (count + 2));
			v.push_back(temp);
			count += 2;
		}
	}

}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.6 MODULAR ARITHMETIC&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Properties &amp;amp; reduction rules&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;(a + b) % m = ( (a % m) + (b % m) ) % m&lt;/strong&gt;
(a * b) % m = ( (a % m) * (b % m) ) % m**&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;For division: need multiplicative inverse modulo m.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Modular Exponentiation (fast powmod)&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hitung a^e mod m efisien dengan binary exponentiation (O(log e)). Sangat penting untuk crypto &amp;amp; CP&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;long long modmul(long long a, long long b, long long mod){
    return (__int128)a*b % mod;
}
long long modpow(long long a, long long e, long long mod){
    long long r = 1 % mod;
    a %= mod;
    while (e){
        if (e &amp;amp; 1) r = modmul(r, a, mod);
        a = modmul(a, a, mod);
        e &amp;gt;&amp;gt;= 1;
    }
    return r;
}
&amp;gt; Use-cases: fast power under mod, Fermat/Euler-based reductions, repeated exponent problems.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Modular inverse&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If gcd(a,m) != 1 inverse mungkin tidak ada.
If m prime: inv(a) = a^{m-2} mod m (Fermat).
&lt;strong&gt;General&lt;/strong&gt;: use Extended Euclidean Algorithm.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;long long extgcd(long long a, long long b, long long &amp;amp;x, long long &amp;amp;y){
    if (b==0){ x=1; y=0; return a; }
    long long x1,y1; long long g = extgcd(b, a%b, x1, y1);
    x = y1;
    y = x1 - (a/b) * y1;
    return g;
}
long long modinv(long long a, long long m){
    long long x,y; long long g = extgcd(a,m,x,y);
    if (g != 1) return -1; // no inverse
    x %= m; if (x&amp;lt;0) x+=m;
    return x;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Exponent reduction (Euler / phi trick)&lt;/strong&gt;
If gcd(a,m)=1, Euler&apos;s theorem: a^{φ(m)} ≡ 1 (mod m). Jadi a^e mod m = a^{ e mod φ(m) } mod m (with care when e &amp;gt;= φ(m) — if exponent itself large, reduce w/ φ and add φ when needed). See Totient section.
Wikipedia&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: &lt;em&gt;When gcd(a,m) != 1, reduction e mod φ(m) is NOT valid. Use CRT or handle separately.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.7 EULER&apos;S TOTIENT&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;/strong&gt;
φ(n) = count of integers 1..n that are coprime with n. (Euler’s totient / phi).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Product / formula&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;If n = ∏ p_i^{k_i}, then
φ(n) = n * ∏_{p | n} (1 - 1/p)
     = ∏ p_i^{k_i-1} * (p_i - 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Compute φ(n)&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;By factorization: factor n, apply product formula (fast if factors known).
For all i ≤ N compute φ via sieve-like method (linear or O(n log log n)):&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;vector&amp;lt;int&amp;gt; phi_sieve(int n){
  vector&amp;lt;int&amp;gt; phi(n+1);
  for (int i=0;i&amp;lt;=n;i++) phi[i]=i;
  for (int p=2;p&amp;lt;=n;p++) if (phi[p]==p){
    for (int k=p;k&amp;lt;=n;k+=p) phi[k] -= phi[k]/p;
  }
  return phi;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Uses&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Euler theorem (a^{φ(n)} ≡ 1 mod n if gcd(a,n)=1).&lt;/li&gt;
&lt;li&gt;Reduce exponents, multiplicative order, compute primitive roots (if exist).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.8 COMBINATORICS &amp;amp; SPECIAL SEQUENCES&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Permutations, combinations, Catalan numbers (handshake problem is Catalan-related — lihat link GfG).&lt;/li&gt;
&lt;li&gt;Quick tip: many &quot;non-crossing&quot; handshake arrangements = Catalan numbers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Factorial &amp;amp; nCr mod (prime)&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Precompute fact[] and invfact[]:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;vector&amp;lt;long long&amp;gt; fact(N+1), invfact(N+1);
fact[0]=1;
for (int i=1;i&amp;lt;=N;i++) fact[i]=fact[i-1]*i%MOD;
invfact[N]=modpow(fact[N], MOD-2, MOD); // MOD prime
for (int i=N;i&amp;gt;0;i--) invfact[i-1]=invfact[i]*i%MOD;
long long nCr(int n,int r){
  if (r&amp;lt;0||r&amp;gt;n) return 0;
  return fact[n]*invfact[r]%MOD*invfact[n-r]%MOD;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Use Lucas theorem for very large n with prime MOD.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Catalan numbers (handshake non-crossing)&lt;/strong&gt;
Number of non-crossing handshake pairings for 2n people = C_n (Catalan). Recurrence:
C_0 = 1, C_{n+1} = Σ_{i=0..n} C_i * C_{n-i}.
AlgoMonster&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Closed form: C_n = (1/(n+1)) * binom(2n, n).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Fibonacci (fast doubling)&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fast doubling computes F(n) mod m in O(log n).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;pair&amp;lt;long long,long long&amp;gt; fib_pair(long long n, long long mod){
  if (n==0) return {0,1};
  auto p = fib_pair(n&amp;gt;&amp;gt;1, mod);
  long long a = p.first, b = p.second;
  long long c = ( (__int128)a * ( (2*b%mod - a + mod) % mod ) ) % mod;
  long long d = ( (__int128)a*a + (__int128)b*b ) % mod;
  if (n%2==0) return {c,d};
  else return {d,(c+d)%mod};
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Short Tips / Pitfalls&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;When reducing exponent using φ: only safe if gcd(base, mod) == 1. Otherwise handle separately or use CRT.&lt;/li&gt;
&lt;li&gt;Always watch overflow: use __int128 on products before %.&lt;/li&gt;
&lt;li&gt;Precompute primes &amp;amp; φ up to N for many queries.&lt;/li&gt;
&lt;li&gt;For modular inverse on composite modulus: inverse may not exist.&lt;/li&gt;
&lt;li&gt;For counting non-crossing structures (like handshake), map to Catalan.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Referensi singkat (untuk baca lebih lanjut)&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Euler%27s_totient_function?utm_source=chatgpt.com&quot;&gt;Euler’s totient (phi) — definition &amp;amp; product formula.&lt;/a&gt;
&lt;em&gt;Wikipedia&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Modular_exponentiation?utm_source=chatgpt.com&quot;&gt;Modular exponentiation — algorithm &amp;amp; notes.&lt;/a&gt;
&lt;em&gt;Wikipedia&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://algo.monster/liteproblems/1259?utm_source=chatgpt.com&quot;&gt;Catalan / Handshakes (non-crossing) — combinatorial derivation.&lt;/a&gt;
&lt;em&gt;AlgoMonster&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Chinese_remainder_theorem?utm_source=chatgpt.com&quot;&gt;Chinese Remainder Theorem — theory &amp;amp; algorithm.&lt;/a&gt;
&lt;em&gt;Wikipedia&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.9 Factorials &amp;amp; nCr (with mod)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Precompute fact[] and invfact[] (using mod inverse) for fast nCk queries.&lt;/li&gt;
&lt;li&gt;Use Lucas theorem for large n with prime mod (advanced).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.9 Factorials &amp;amp; nCr (with mod)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; hitung C(n, r) mod M (binomial coefficient modulo M) secara efisien untuk berbagai kasus:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;banyak query dengan n ≤ N (precompute factorial)&lt;/li&gt;
&lt;li&gt;n besar tapi M kecil prime (Lucas theorem)&lt;/li&gt;
&lt;li&gt;catatan untuk M bukan prime (kompleksitas lebih tinggi — overview)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Konsep singkat&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Binomial coefficient:&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;C(n, r) = n! / (r! * (n-r)!)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Untuk modulus &lt;code&gt;M&lt;/code&gt; (biasanya prime), kita pakai fakta&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C(n, r) mod M = fact[n] * invfact[r] * invfact[n-r] (mod M)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;dengan &lt;code&gt;invfact[x]&lt;/code&gt; = modular inverse dari &lt;code&gt;fact[x]&lt;/code&gt; modulo &lt;code&gt;M&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Modular inverse untuk prime &lt;code&gt;M&lt;/code&gt; bisa dihitung dengan &lt;code&gt;a^(M-2) mod M&lt;/code&gt; (Fermat).&lt;br /&gt;
Jika &lt;code&gt;M&lt;/code&gt; bukan prime: gunakan extended gcd atau dekomposisi modulus ke prime-power + CRT (lihat catatan di bawah).&lt;/p&gt;
&lt;h2&gt;Precompute factorial &amp;amp; inverse factorial (MOD prime, banyak query, n ≤ MAXN)&lt;/h2&gt;
&lt;p&gt;Kompleksitas: O(MAXN) preprocessing, O(1) per query.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
using int64 = long long;
const int64 MOD = 1000000007; // example prime mod

int64 modmul(int64 a, int64 b, int64 mod=MOD){
    return (__int128)a * b % mod;
}
int64 modpow(int64 a, int64 e, int64 mod=MOD){
    int64 r = 1;
    a %= mod;
    while (e){
        if (e &amp;amp; 1) r = modmul(r, a, mod);
        a = modmul(a, a, mod);
        e &amp;gt;&amp;gt;= 1;
    }
    return r;
}

struct Binom {
    int N;
    int64 mod;
    vector&amp;lt;int64&amp;gt; fact, invfact;
    Binom(int N_, int64 mod_ = MOD) : N(N_), mod(mod_), fact(N_+1), invfact(N_+1) {
        fact[0] = 1;
        for (int i = 1; i &amp;lt;= N; ++i) fact[i] = modmul(fact[i-1], i, mod);
        invfact[N] = modpow(fact[N], mod-2, mod); // only if mod is prime
        for (int i = N; i &amp;gt;= 1; --i) invfact[i-1] = modmul(invfact[i], i, mod);
    }
    int64 nCr(int n, int r) {
        if (r &amp;lt; 0 || r &amp;gt; n) return 0;
        return modmul(fact[n], modmul(invfact[r], invfact[n-r], mod), mod);
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Jika n maksimal 1e6 dan banyak query → precompute Binom(1e6) lalu nCr(n,r) O(1).&lt;/li&gt;
&lt;li&gt;Jangan precompute lebih besar dari memori/time budget.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lucas Theorem (untuk n besar, mod = prime but small p)&lt;/strong&gt;
Lucas: jika p prime, representasikan n dan r dalam base p:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;n = n_k p^k + ... + n_0
r = r_k p^k + ... + r_0
C(n, r) ≡ Π_{i=0..k} C(n_i, r_i) (mod p)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dengan &lt;strong&gt;C(n_i, r_i)&lt;/strong&gt; dihitung biasa &lt;em&gt;&lt;strong&gt;(precompute factorial up to p-1)&lt;/strong&gt;&lt;/em&gt;. Jika untuk suatu digit &lt;strong&gt;r_i &amp;gt; n_i&lt;/strong&gt; maka C(...) = 0.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Kapan gunakan:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;p kecil (misal p ≤ 1e6) dan n bisa besar (≥ p).&lt;/li&gt;
&lt;li&gt;Precompute O(p) untuk factorial, setiap query O(log_p n) langkah.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Implementasi Lucas (mengasumsikan precompute fact &amp;amp; invfact untuk 0..p-1):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// precompute factorials up to p-1
vector&amp;lt;int64&amp;gt; factP, invfactP;
void prep_p(int p, int64 mod) {
    factP.assign(p, 0);
    invfactP.assign(p, 0);
    factP[0] = 1;
    for (int i = 1; i &amp;lt; p; ++i) factP[i] = modmul(factP[i-1], i, mod);
    invfactP[p-1] = modpow(factP[p-1], mod-2, mod);
    for (int i = p-1; i &amp;gt;= 1; --i) invfactP[i-1] = modmul(invfactP[i], i, mod);
}

int64 nCr_small(int n, int r, int64 mod) {
    if (r &amp;lt; 0 || r &amp;gt; n) return 0;
    return modmul(factP[n], modmul(invfactP[r], invfactP[n-r], mod), mod);
}

// Lucas
int64 lucas(int64 n, int64 r, int p, int64 mod) {
    if (r == 0) return 1;
    int64 ni = n % p;
    int64 ri = r % p;
    if (ri &amp;gt; ni) return 0;
    return modmul(lucas(n / p, r / p, p, mod), nCr_small(ni, ri, mod), mod);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Catatan&lt;/strong&gt;: jika &lt;strong&gt;mod&lt;/strong&gt; besar prime (mis. 1e9+7), precomputing up to &lt;strong&gt;mod-1&lt;/strong&gt; is impractical, gunakan precompute factorial sampai &lt;strong&gt;max_n&lt;/strong&gt; yang diperlukan (lihat bagian Precompute di atas). Lucas berguna kalau p kecil.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Kummer&apos;s theorem (ekspresi p-adic / kapan binomial divisible by p)&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Banyak berguna untuk memeriksa apakah C(n,r) ≡ 0 (mod p).&lt;/li&gt;
&lt;li&gt;Kummer: pangkat prima p yang membagi C(n,r) = jumlah carry ketika menambahkan r dan n-r dalam base p.&lt;/li&gt;
&lt;li&gt;Jika ada carry → exponent &amp;gt; 0 → hasil ≡ 0 (mod p).&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ini mendasari kenapa Lucas work: jika ada digit r_i &amp;gt; n_i → carry → kombinasi digit bernilai 0.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Catatan: MOD bukan prime (overview)&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Jika modulus M non-prime (mis M = ∏ p_i^{e_i}), compute C(n,r) mod M biasanya via&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Untuk tiap prime-power p^e compute C(n,r) mod p^e (butuh algoritma yang memperhitungkan p-adic valuation, faktorial modulo p^e, dan lifting — mis. Lucas generalization / Lucas untuk prime powers / use of factorial without multiples of p + combine via CRT).&lt;/li&gt;
&lt;li&gt;Gabungkan hasil tiap p^e dengan CRT.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Implementasi lengkap relatif panjang dan rentan bug — gunakan library/known implementations jika perlu (contoh: implementasi untuk nCr mod p^k yang memakai p-adic factorial &amp;amp; Garner).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Untuk kompetisi: jika M composite tapi kecil, sering lebih mudah dekomposisi modulus dulu.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Contoh lengkap (menggabungkan kedua pendekatan)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Kasus A: banyak query, n &amp;lt;= 2e6, MOD=1e9+7 (prime) → gunakan Binom precompute.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kasus B: n up to 1e18, MOD = small prime (e.g. 1000003) → gunakan Lucas dengan precompute up to p-1.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Minimal working example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// contoh: MOD = 1&apos;000&apos;003 (prime, but small enough for Lucas precompute)
#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
using int64 = long long;
int64 MOD = 1000003;
vector&amp;lt;int64&amp;gt; factP, invfactP;
int64 modmul(int64 a, int64 b){ return (__int128)a*b%MOD; }
int64 modpow(int64 a, int64 e){
    int64 r=1; a%=MOD;
    while(e){ if(e&amp;amp;1) r=modmul(r,a); a=modmul(a,a); e&amp;gt;&amp;gt;=1; }
    return r;
}
void prep_p(int p){
    factP.assign(p,0); invfactP.assign(p,0);
    factP[0]=1;
    for(int i=1;i&amp;lt;p;++i) factP[i]=modmul(factP[i-1], i);
    invfactP[p-1]=modpow(factP[p-1], MOD-2);
    for(int i=p-1;i&amp;gt;=1;--i) invfactP[i-1] = modmul(invfactP[i], i);
}
int64 nCr_small(int n, int r){
    if (r&amp;lt;0 || r&amp;gt;n) return 0;
    return modmul(factP[n], modmul(invfactP[r], invfactP[n-r]));
}
int64 lucas(long long n, long long r, int p){
    if (r==0) return 1;
    int64 ni = n % p;
    int64 ri = r % p;
    if (ri &amp;gt; ni) return 0;
    return modmul(lucas(n/p, r/p, p), nCr_small((int)ni,(int)ri));
}
int main(){
    prep_p((int)MOD);
    // contoh: compute C(10^12, 123456) mod 1000003
    long long n = 1000000000000LL;
    long long r = 123456;
    cout &amp;lt;&amp;lt; lucas(n, r, (int)MOD) &amp;lt;&amp;lt; &quot;\n&quot;;
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pitfalls &amp;amp; practical tips&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Overflow: gunakan __int128 saat mengalikan sebelum mod.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MOD must be prime untuk cara simple invfact[N] = fact[N]^(MOD-2). Jika MOD bukan prime, fact[N] mungkin tidak invertible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Precompute size: hanya precompute sampai max_n yang benar-benar diperlukan (ingat memori).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lucas precompute cost: butuh O(p) memory/time — only practical jika p kecil.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edge cases: C(n, 0) = 1; C(n, r)=0 jika r&amp;gt;n.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Composite MOD: jika harus, cari library atau pakai dekomposisi prime-power + CRT.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Ringkasan&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Jika MOD prime dan n bounded → precompute factorial &amp;amp; invfact, O(1) per query.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jika n besar &amp;amp; MOD small prime → Lucas theorem.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jika MOD composite → dekomposisi &amp;amp; CRT atau advanced p-adic algorithms.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h2&gt;2. BRUTE FORCE&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt; : small constraints (n ≤ 10-20), or to prototype.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tips&lt;/strong&gt; : prune early, use bitmasking for subsets, memoize repeated states.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Subset enumeration (bitmask):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;for (int mask=0; mask &amp;lt; (1&amp;lt;&amp;lt;n); ++mask) {
    // process subset represented by mask
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h2&gt;3. GREEDY&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pattern checklist&lt;/strong&gt;:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Can a local optimal choice lead to global optimal? Prove or counterexample.&lt;/li&gt;
&lt;li&gt;Sorting often precedes greedy solution.&lt;/li&gt;
&lt;li&gt;Typical problems: interval scheduling, Huffman, fractional knapsack.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pitfall&lt;/strong&gt;: Greedy works for some variants (e.g., fractional knapsack) but fails for others (0/1 knapsack).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h2&gt;4. DYNAMIC PROGRAMMING&lt;/h2&gt;
&lt;h3&gt;4.1 Knapsack&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;0/1 Knapsack (DP by weight):
// n items, capacity W
vector&amp;lt;int&amp;gt; dp(W+1, 0);
for (int i=0;i&amp;lt;n;i++){
  for (int w=W; w&amp;gt;=wt[i]; --w)
    dp[w] = max(dp[w], dp[w-wt[i]] + val[i]);
}

Unbounded Knapsack:
for (int i=0;i&amp;lt;n;i++)
  for (int w=wt[i]; w&amp;lt;=W; ++w)
    dp[w] = max(dp[w], dp[w-wt[i]] + val[i]);

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;: Choose state carefully (by weight, by value, or by items). Track reconstruction if needed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4.2 DP tips&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Identify state and transition clearly.&lt;/li&gt;
&lt;li&gt;Try to reduce dimensions (rolling arrays).&lt;/li&gt;
&lt;li&gt;Use -INF for impossible states.&lt;/li&gt;
&lt;li&gt;For optimization: monotone queues, convex hull trick (advanced).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h2&gt;5. TWO POINTERS&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Use when&lt;/strong&gt;: array sorted or window on sequence; finding pairs/triples with certain sum; partitioning.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Two-sum on sorted array (O(n))&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int l=0, r=n-1;
while (l&amp;lt;r) {
  int s = a[l]+a[r];
  if (s==target) { /* found */ break; }
  else if (s&amp;lt;target) ++l;
  else --r;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tips&lt;/strong&gt;: For arrays that are not sorted, either sort (if order not needed) or use hash-based two-sum.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h2&gt;6. SLIDING WINDOW&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Patterns&lt;/strong&gt;:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Fixed-size window: maintain sum/structure while moving window.&lt;/li&gt;
&lt;li&gt;Variable-size window: expand/contract based on condition (common for max/min subarray with constraint).
&lt;strong&gt;Max sum of subarray of size k:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;long long sum=0;
for (int i=0;i&amp;lt;k;i++) sum += a[i];
long long best = sum;
for (int i=k;i&amp;lt;n;i++){
  sum += a[i] - a[i-k];
  best = max(best, sum);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Variable window (smallest subarray with sum ≥ S):&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int l=0; long long sum=0; int ans = INF;
for (int r=0;r&amp;lt;n;r++){
  sum += a[r];
  while (sum &amp;gt;= S) {
    ans = min(ans, r-l+1);
    sum -= a[l++];
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h2&gt;7. GRAPHS&lt;/h2&gt;
&lt;p&gt;| &lt;strong&gt;Kapan + Contoh soal + Solusi + Implementasi&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;7.1 BFS (Breadth-First Search)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;When&lt;/strong&gt; : shortest path di graph unweighted, connectivity, level-order, shortest&lt;/li&gt;
&lt;li&gt;transformation (word ladder), multi-source BFS.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Problem&lt;/strong&gt; (contoh): Diberi graph tak-berbobot dan source s, cari jarak minimal ke semua node.
Idea: queue, dist[], O(V+E).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;// BFS for unweighted shortest paths
#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
using ll = long long;
const int INF = 1e9;
vector&amp;lt;int&amp;gt; bfs(int src, const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; adj){
    int n = adj.size();
    vector&amp;lt;int&amp;gt; dist(n, INF);
    queue&amp;lt;int&amp;gt; q;
    dist[src] = 0; q.push(src);
    while(!q.empty()){
        int u = q.front(); q.pop();
        for(int v: adj[u]) if (dist[v] == INF){
            dist[v] = dist[u] + 1;
            q.push(v);
        }
    }
    return dist;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.2 Dijkstra (non-negative weights)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;When&lt;/strong&gt;: shortest path di graph dengan bobot ≥ 0.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Problem&lt;/strong&gt;: shortest path dari s ke semua node (weighted).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Idea&lt;/strong&gt;: priority_queue (min-heap), relax edges, O((V+E) log V).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
using ll = long long;
const ll INF = (1LL&amp;lt;&amp;lt;60);
vector&amp;lt;ll&amp;gt; dijkstra(int src, const vector&amp;lt;vector&amp;lt;pair&amp;lt;int,ll&amp;gt;&amp;gt;&amp;gt;&amp;amp; adj){
    int n = adj.size();
    vector&amp;lt;ll&amp;gt; dist(n, INF);
    priority_queue&amp;lt;pair&amp;lt;ll,int&amp;gt;, vector&amp;lt;pair&amp;lt;ll,int&amp;gt;&amp;gt;, greater&amp;lt;&amp;gt;&amp;gt; pq;
    dist[src]=0; pq.push({0,src});
    while(!pq.empty()){
        auto [d,u] = pq.top(); pq.pop();
        if (d != dist[u]) continue;
        for (auto [v,w] : adj[u]){
            if (dist[v] &amp;gt; d + w){
                dist[v] = d + w;
                pq.push({dist[v], v});
            }
        }
    }
    return dist;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.3 Bellman–Ford (neg. weights, detect negative cycles)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: edge weight bisa negatif, perlu deteksi negative cycle (single-source).
&lt;strong&gt;Problem&lt;/strong&gt;: shortest path dengan bobot negatif.
&lt;strong&gt;Idea&lt;/strong&gt;: relax semua edge V-1 kali; cek relaksasi ke-V untuk negative cycle. O(V·E).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
using ll = long long;
const ll INF = (1LL&amp;lt;&amp;lt;60);
struct Edge { int u,v; ll w; };
pair&amp;lt;vector&amp;lt;ll&amp;gt;, bool&amp;gt; bellman_ford(int n, int src, const vector&amp;lt;Edge&amp;gt;&amp;amp; edges){
    vector&amp;lt;ll&amp;gt; dist(n, INF); dist[src]=0;
    for(int i=0;i&amp;lt;n-1;i++){
        for(auto &amp;amp;e: edges){
            if (dist[e.u] != INF &amp;amp;&amp;amp; dist[e.v] &amp;gt; dist[e.u] + e.w)
                dist[e.v] = dist[e.u] + e.w;
        }
    }
    bool negcycle = false;
    for(auto &amp;amp;e: edges){
        if (dist[e.u] != INF &amp;amp;&amp;amp; dist[e.v] &amp;gt; dist[e.u] + e.w) { negcycle = true; break; }
    }
    return {dist, negcycle};
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.4 Kruskal (MST) + DSU&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: cari MST di graph tak-berbobot/berbobot (undirected).
&lt;strong&gt;Problem&lt;/strong&gt;: minimum spanning tree total weight.
&lt;strong&gt;Idea&lt;/strong&gt;: urutkan edges by weight, unite jika beda komponen (DSU). O(E log E).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
using ll = long long;
struct DSU {
    vector&amp;lt;int&amp;gt; p, r;
    DSU(int n): p(n), r(n,0){ iota(p.begin(), p.end(), 0); }
    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }
    bool unite(int a,int b){
        a=find(a); b=find(b);
        if (a==b) return false;
        if (r[a]&amp;lt;r[b]) swap(a,b);
        p[b]=a; if (r[a]==r[b]) r[a]++; return true;
    }
};
ll kruskal(int n, vector&amp;lt;tuple&amp;lt;ll,int,int&amp;gt;&amp;gt;&amp;amp; edges){
    sort(edges.begin(), edges.end());
    DSU dsu(n); ll cost=0;
    for(auto &amp;amp;t : edges){
        ll w; int u,v; tie(w,u,v)=t;
        if (dsu.unite(u,v)) cost += w;
    }
    return cost;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.5 Prim (MST) — adjacency list&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: sering berguna bila graph besar dan E ~ V^2, atau ingin implementasi langsung dari node.
&lt;strong&gt;Idea&lt;/strong&gt;: greedy pick min edge crossing current tree, priority_queue. O(E log V).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
using ll = long long;
ll prim(int src, const vector&amp;lt;vector&amp;lt;pair&amp;lt;int,ll&amp;gt;&amp;gt;&amp;gt;&amp;amp; adj){
    int n = adj.size();
    vector&amp;lt;char&amp;gt; used(n,false);
    priority_queue&amp;lt;pair&amp;lt;ll,int&amp;gt;, vector&amp;lt;pair&amp;lt;ll,int&amp;gt;&amp;gt;, greater&amp;lt;&amp;gt;&amp;gt; pq;
    pq.push({0,src});
    ll total=0;
    while(!pq.empty()){
        auto [w,u]=pq.top(); pq.pop();
        if (used[u]) continue;
        used[u]=1; total += w;
        for(auto [v,wt] : adj[u]) if (!used[v]) pq.push({wt,v});
    }
    return total;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.6 Topological Sort &amp;amp; DP on DAG&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: DAG problems: task ordering, DP longest path on DAG, counting paths.
&lt;strong&gt;Problem&lt;/strong&gt;: hitung panjang jalur terpanjang di DAG.
&lt;strong&gt;Idea&lt;/strong&gt;: topo sort (Kahn) → relax outgoing edges in topo order → O(V+E).&lt;/p&gt;
&lt;p&gt;(topo + longest path):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
using ll = long long;
vector&amp;lt;int&amp;gt; topo_kahn(const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; adj){
    int n = adj.size();
    vector&amp;lt;int&amp;gt; indeg(n,0), res;
    for(int u=0;u&amp;lt;n;u++) for(int v: adj[u]) indeg[v]++;
    queue&amp;lt;int&amp;gt; q;
    for(int i=0;i&amp;lt;n;i++) if (indeg[i]==0) q.push(i);
    while(!q.empty()){
        int u=q.front(); q.pop(); res.push_back(u);
        for(int v: adj[u]) if (--indeg[v]==0) q.push(v);
    }
    return res; // if size &amp;lt; n =&amp;gt; cycle exists
}
vector&amp;lt;ll&amp;gt; longest_on_dag(const vector&amp;lt;vector&amp;lt;pair&amp;lt;int,ll&amp;gt;&amp;gt;&amp;gt;&amp;amp; adj, int src){
    int n = adj.size();
    auto topo = topo_kahn(vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;(n)); // build simple adj for indeg? assume we have topo
    // In practice build topo from original adj (unweighted) or convert.
    // Here just pattern - implement according to input.
    vector&amp;lt;ll&amp;gt; dp(n, LLONG_MIN/4);
    dp[src]=0;
    for(int u: topo) if (dp[u] &amp;gt; LLONG_MIN/4){
        for(auto [v,w] : adj[u]) dp[v] = max(dp[v], dp[u] + w);
    }
    return dp;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Note: sesuaikan pembuatan topo jika adj berisi pair; konsep tetap sama.)&lt;/p&gt;
&lt;h3&gt;7.7 SCC (Kosaraju / Tarjan)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: directed graph, perlu komponen kuat terhubung (2-SAT, condensation graph).
&lt;strong&gt;Problem&lt;/strong&gt;: hitung SCC dan buat DAG komponen.
&lt;strong&gt;Idea&lt;/strong&gt; (Kosaraju): DFS order → reverse graph → DFS in reverse order. Tarjan lebih ringkas (1 pass).&lt;/p&gt;
&lt;p&gt;Kosaraju Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
void kosaraju(int n, const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; adj, vector&amp;lt;int&amp;gt;&amp;amp; comp){
    vector&amp;lt;int&amp;gt; order; vector&amp;lt;char&amp;gt; vis(n,false);
    function&amp;lt;void(int)&amp;gt; dfs1 = [&amp;amp;](int u){
        vis[u]=1;
        for(int v: adj[u]) if(!vis[v]) dfs1(v);
        order.push_back(u);
    };
    for(int i=0;i&amp;lt;n;i++) if(!vis[i]) dfs1(i);
    vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; radj(n);
    for(int u=0;u&amp;lt;n;u++) for(int v: adj[u]) radj[v].push_back(u);
    comp.assign(n, -1);
    function&amp;lt;void(int,int)&amp;gt; dfs2 = [&amp;amp;](int u,int cid){
        comp[u]=cid;
        for(int v: radj[u]) if(comp[v]==-1) dfs2(v,cid);
    };
    int cid=0;
    for(int i=n-1;i&amp;gt;=0;i--){
        int u = order[i];
        if (comp[u]==-1) { dfs2(u, cid++); }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.8 Bridges &amp;amp; Articulation Points (Tarjan cut-edge / cut-vertex)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: cari edges/vertices yang jika dihapus meningkatkan jumlah komponen (kritikal roads).
&lt;strong&gt;Problem&lt;/strong&gt;: listing all bridges.
&lt;strong&gt;Idea&lt;/strong&gt;: DFS track tin[u] dan low[u]. Bridge u-v jika low[v] &amp;gt; tin[u].&lt;/p&gt;
&lt;p&gt;(bridges):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
int timer;
vector&amp;lt;int&amp;gt; tin, low;
vector&amp;lt;pair&amp;lt;int,int&amp;gt;&amp;gt; bridges;
void dfs_bridge(int u, int p, const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; adj){
    tin[u]=low[u]=++timer;
    for(int v: adj[u]){
        if (v==p) continue;
        if (tin[v]) { low[u] = min(low[u], tin[v]); }
        else {
            dfs_bridge(v, u, adj);
            low[u] = min(low[u], low[v]);
            if (low[v] &amp;gt; tin[u]) bridges.push_back({u,v});
        }
    }
}
void find_bridges(const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; adj){
    int n = adj.size();
    timer = 0; tin.assign(n,0); low.assign(n,0); bridges.clear();
    for(int i=0;i&amp;lt;n;i++) if(!tin[i]) dfs_bridge(i,-1,adj);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.9 Lowest Common Ancestor (LCA) — Binary Lifting&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: frequent queries LCA/kth ancestor/distance on tree.
&lt;strong&gt;Problem&lt;/strong&gt;: berapa LCA(u,v)? hitung jarak.
&lt;strong&gt;Idea&lt;/strong&gt;: preprocess up[k][v], depth[], jump. O(N log N) preprocess, O(log N) query.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
int LOG;
vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; up;
vector&amp;lt;int&amp;gt; depth;
void dfs_lca(int u, int p, const vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&amp;amp; adj){
    up[0][u] = (p&amp;lt;0?u:p);
    for (int k=1;k&amp;lt;LOG;k++) up[k][u] = up[k-1][ up[k-1][u] ];
    for (int v: adj[u]) if (v!=p){
        depth[v] = depth[u] + 1;
        dfs_lca(v, u, adj);
    }
}
int lca(int a, int b){
    if (depth[a] &amp;lt; depth[b]) swap(a,b);
    int diff = depth[a] - depth[b];
    for (int k=0; k&amp;lt;LOG; ++k) if (diff &amp;amp; (1&amp;lt;&amp;lt;k)) a = up[k][a];
    if (a==b) return a;
    for (int k=LOG-1;k&amp;gt;=0;k--) if (up[k][a] != up[k][b]) { a = up[k][a]; b = up[k][b]; }
    return up[0][a];
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.10 Max Flow — Dinic (practical)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: problems modelled as flow: circulation, bipartite matching, disjoint paths, max flow min cut.
&lt;strong&gt;Problem&lt;/strong&gt; (contoh): bipartite matching → convert to flow, run Dinic.
&lt;strong&gt;Idea&lt;/strong&gt;: level graph (BFS), blocking flow (DFS), repeated.&lt;/p&gt;
&lt;p&gt;(Dinic):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
using ll = long long;
struct Dinic {
  struct Edge { int to; ll cap; int rev; };
  int n; vector&amp;lt;vector&amp;lt;Edge&amp;gt;&amp;gt; g; vector&amp;lt;int&amp;gt; level, it;
  Dinic(int n): n(n), g(n), level(n), it(n) {}
  void add_edge(int u,int v,ll c){
    g[u].push_back({v,c,(int)g[v].size()});
    g[v].push_back({u,0,(int)g[u].size()-1});
  }
  bool bfs(int s,int t){
    fill(level.begin(), level.end(), -1);
    queue&amp;lt;int&amp;gt; q; q.push(s); level[s]=0;
    while(!q.empty()){
      int u=q.front(); q.pop();
      for(auto &amp;amp;e: g[u]) if (e.cap&amp;gt;0 &amp;amp;&amp;amp; level[e.to]==-1){
        level[e.to] = level[u]+1; q.push(e.to);
      }
    }
    return level[t] != -1;
  }
  ll dfs(int u,int t,ll f){
    if (!f) return 0;
    if (u==t) return f;
    for (int &amp;amp;i = it[u]; i &amp;lt; (int)g[u].size(); ++i){
      Edge &amp;amp;e = g[u][i];
      if (e.cap&amp;gt;0 &amp;amp;&amp;amp; level[e.to] == level[u] + 1){
        ll ret = dfs(e.to, t, min(f, e.cap));
        if (ret){
          e.cap -= ret; g[e.to][e.rev].cap += ret;
          return ret;
        }
      }
    }
    return 0;
  }
  ll maxflow(int s,int t){
    ll flow = 0;
    while(bfs(s,t)){
      fill(it.begin(), it.end(), 0);
      while (ll f = dfs(s,t, LLONG_MAX)) flow += f;
    }
    return flow;
  }
};

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Contoh penggunaan&lt;/strong&gt; (bipartite matching): buat source → kiri nodes cap 1 → edges → kanan nodes cap1 → sink; maxflow = matching size.&lt;/p&gt;
&lt;h3&gt;7.11 Hopcroft–Karp (bipartite matching specialized)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: maximum bipartite matching faster in practice: O(√V · E).
&lt;strong&gt;Problem&lt;/strong&gt;: matching on big bipartite graphs.
&lt;strong&gt;Idea&lt;/strong&gt;: BFS levels + DFS augmenting.&lt;/p&gt;
&lt;p&gt;(Karena panjang, gunakan template tim; kalau mau aku tambahkan full code Hopcroft-Karp.)&lt;/p&gt;
&lt;h3&gt;7.12 Tree DP — contoh: diameter, subtree sums&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt;: penyelesaian masalah pada tree (dp per node): subtree aggregations, rerooting.
&lt;strong&gt;Problem&lt;/strong&gt; (contoh): tree diameter (longest path).
&lt;strong&gt;Idea&lt;/strong&gt; (diameter): dua BFS/DFS: pick any node → furthest a → from a furthest b → distance(a,b) = diameter.&lt;/p&gt;
&lt;p&gt;Code (diameter):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pair&amp;lt;int,int&amp;gt; farthest(int src, const vector&amp;lt;vector&amp;lt;pair&amp;lt;int,int&amp;gt;&amp;gt;&amp;gt;&amp;amp; adj){
    int n = adj.size();
    vector&amp;lt;int&amp;gt; dist(n, -1);
    queue&amp;lt;int&amp;gt; q;
    q.push(src); dist[src]=0;
    while(!q.empty()){
        int u=q.front(); q.pop();
        for(auto [v,w]: adj[u]) if (dist[v]==-1){
            dist[v] = dist[u] + w; q.push(v);
        }
    }
    int best = 0, node = src;
    for(int i=0;i&amp;lt;n;i++) if (dist[i] &amp;gt; best) best = dist[i], node = i;
    return {node, best};
}
// diameter:
int tree_diameter(const vector&amp;lt;vector&amp;lt;pair&amp;lt;int,int&amp;gt;&amp;gt;&amp;gt;&amp;amp; adj){
    auto p = farthest(0, adj);
    auto q = farthest(p.first, adj);
    return q.second;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.13 Common patterns &amp;amp; mapping problem→algorithm&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If unweighted shortest path → BFS.&lt;/li&gt;
&lt;li&gt;If non-neg weights → Dijkstra.&lt;/li&gt;
&lt;li&gt;If neg weights allowed → Bellman-Ford (or Johnson if all-pairs).&lt;/li&gt;
&lt;li&gt;If MST → Kruskal/Prim.&lt;/li&gt;
&lt;li&gt;If maximum flow / matching → Dinic / Hopcroft-Karp.&lt;/li&gt;
&lt;li&gt;If SCC / 2-SAT → Kosaraju/Tarjan.&lt;/li&gt;
&lt;li&gt;If bridges/articulation → Tarjan low/tin.&lt;/li&gt;
&lt;li&gt;If LCA / tree queries → binary lifting + Euler tour + segtree.&lt;/li&gt;
&lt;li&gt;If DAG dp → topo sort → DP.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h2&gt;8. CLASSIC PUZZLES / LINKS&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://share.google/3gpDL8D2vs6LWh3NP&quot;&gt;&lt;strong&gt;Number of Ways to Handshakes That Don&apos;t Cross — related to Catalan numbers(non-crossing matchings)&lt;/strong&gt;&lt;/a&gt;. &lt;em&gt;GFG&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://share.google/I8Buc1xX6cC8SYjfd&quot;&gt;&lt;strong&gt;The Water Jug Problem - Count Min Steps — BFS on state-space (jugs as states) or use math for solvability via gcd&lt;/strong&gt;&lt;/a&gt;. &lt;em&gt;GFG&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Quick note&lt;/strong&gt; (Water Jug): solvable iff target % gcd(capA, capB) == 0. Minimum steps: simulate BFS on states (a,b).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h2&gt;9.Useful helpers&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;clamp, min/max patterns, lower_bound/upper_bound for binary search.&lt;/li&gt;
&lt;li&gt;__int128 for safe multiplication before mod.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h2&gt;99 Contoh Problem&lt;/h2&gt;
&lt;h3&gt;99.1. Jumlah dari Jumlah (Take/NoTake [Recursive]):&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;Terdapat sebuah bilangan bulat positif S dan operator  + . Anda dapat membuat bilangan baru X yang merupakan hasil dari menempatkan nol atau lebih operator  +  di tengah dua digit bilangan S. Berikan jumlah dari seluruh kemungkinan bilangan X.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Input&lt;/strong&gt;
Baris pertama berisi bilangan bulat &lt;strong&gt;S (1 ≤ |S| ≤ 9)&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;
Jumlah dari seluruh kemungkinan bilangan X.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Input:
1312

Output:
1856
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;Input:
1234567

Output:
1757440
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;
Untuk test case pertama, berikut merupakan setiap kemungkinan dari X.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1312&lt;/li&gt;
&lt;li&gt;1 + 312 = 313&lt;/li&gt;
&lt;li&gt;13 + 12 = 25&lt;/li&gt;
&lt;li&gt;131 + 2 = 133&lt;/li&gt;
&lt;li&gt;1 + 3 + 12 = 16&lt;/li&gt;
&lt;li&gt;1 + 31 + 2 = 34&lt;/li&gt;
&lt;li&gt;13 + 1 + 2 = 16&lt;/li&gt;
&lt;li&gt;1 + 3 + 1 + 2 = 7&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sehingga&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;jumlah dari seluruh X adalah: 1312 + 313 + 25 + 133 + 16 + 34 + 16 + 7 = 1856.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;IPLEMENTASI 1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;

#define int long long
int eval_and_print(const string &amp;amp;s) {
    int n = s.size();
    int m = 1 &amp;lt;&amp;lt; (n-1); // setiap bit i =&amp;gt; ada + setelah posisi i (0-based)
    int total = 0;
    for (int mask = 0; mask &amp;lt; m; ++mask) {
        long long cur = 0, sum = 0;
        string expr;
        for (int i = 0; i &amp;lt; n; ++i) {
            cur = cur*10 + (s[i]-&apos;0&apos;);
            expr.push_back(s[i]);
            if (i &amp;lt; n-1 &amp;amp;&amp;amp; (mask &amp;amp; (1&amp;lt;&amp;lt;i))) {
                // add &quot;+&quot; setelah i
                sum += cur;
                cur = 0;
                expr.push_back(&apos;+&apos;);
            }
        }
        sum += cur;
        cout &amp;lt;&amp;lt; expr &amp;lt;&amp;lt; &quot; = &quot; &amp;lt;&amp;lt; sum &amp;lt;&amp;lt; &quot;\n&quot;;
        total += sum;
    }
    cout &amp;lt;&amp;lt; &quot;TOTAL = &quot; &amp;lt;&amp;lt; total &amp;lt;&amp;lt; &quot;\n&quot;;
    return total;
}

signed main(){
    string s;
    if (!(cin &amp;gt;&amp;gt; s)) return 0;
    eval_and_print(s);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;IPLEMENTASI 2&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
using namespace std;
#define ll long long

struct DATA {
	int l, x, r;
};

// Function to find all substrings
vector&amp;lt;DATA&amp;gt; findSubstrings(string &amp;amp;s) {

	// to store all substrings
	vector&amp;lt;DATA&amp;gt; res;
	vector&amp;lt;DATA&amp;gt;v;
	for (int i = 0; i &amp;lt; s.length(); i++) {
		for (int j = i; j &amp;lt; s.length(); j++) {http://localhost:4321/posts/cheatsheet_cp/#3-greedy

			// substr function takes starting index
			// and length as parameters
			res.push_back({i, stoi(s.substr(i, j - i + 1)), (s.size() - (j + 1))});

////			cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot; &quot; &amp;lt;&amp;lt; res[j] &amp;lt;&amp;lt; &quot; &quot; &amp;lt;&amp;lt; s.size() - (j + 1) &amp;lt;&amp;lt; &apos;\n&apos;;
//			v.push_back({i, stoi(res[j]), (s.size() - (j + 1))});
		}
	}

	return res;
}

int main() {
	string s;
	ll sum{0};
	cin &amp;gt;&amp;gt; s;
	int dp[30];
	dp[0] = 1;
	dp[1] = 1;
	for (int i = 2; i &amp;lt; 30; i++) {
		dp[i] = dp[i - 1] * 2;
	}
	vector&amp;lt;DATA&amp;gt; res = findSubstrings(s);
	for (auto i : res) {
//		cout &amp;lt;&amp;lt; i.l &amp;lt;&amp;lt; &quot; &quot; &amp;lt;&amp;lt; i.x &amp;lt;&amp;lt; &quot; &quot; &amp;lt;&amp;lt; i.r &amp;lt;&amp;lt; &apos;\n&apos;;
		//1=1
		//2=2
		//3=4
		//4=8
		sum += (dp[i.l] * dp[i.r] * i.x);
	}
	cout &amp;lt;&amp;lt; sum &amp;lt;&amp;lt; &apos;\n&apos;;
	return 0;
}
/*

REFF:
https://www.geeksforgeeks.org/dsa/program-print-substrings-given-string/

*/

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;99.2. Meledak (DFS [GRAFF]):&lt;/h2&gt;
&lt;hr /&gt;
&lt;p&gt;Bayu adalah seorang perakit bom. Saat ini Bayu memiliki K buah bom waktu yang akan meledak dalam waktu 30 menit setelah dipicu. Dengan bom-bom ini, Ia berencana meledakkan server situs-situs judi daring yang ada di Indonesia. Bayu telah melacak dan akhirnya menemukan N buah lokasi tempat server berada. Dia pun mengetahui bahwa server yang berada di salah satu lokasi memiliki hubungan dengan server yang ada di lokasi lain, sedemikian sehingga jika salah satu server diledakkan, maka server yang memiliki hubungan tersebut juga akan ikut mati. Hubungan ini merupakan hubungan dua arah sehingga jika server a berhubungan dengan server b maka, jika a diledakkan maka b akan mati, dan jika b diledakkan maka a akan mati. Selain itu, jika server c mati karena meledak ataupun mati karena memiliki hubungan dengan server lain, maka semua server yang berhubungan dengan c juga akan mati. Suatu server c juga dapat memiliki hubungan dengan lebih dari satu server lain.&lt;/p&gt;
&lt;p&gt;Di luar dugaan Bayu, terdapat M buah lokasi server yang sudah menempatkan ahli penjinak bom untuk situasi seperti ini, sehingga tentunya Bayu tidak akan memasang bom di lokasi ini. Jika Ia ingin membuat server di lokasi dengan penjinak bom mati, Ia hanya perlu mencari server lain yang memiliki hubungan tetapi tidak memiliki ahli penjinak bom. Bayu memutuskan untuk menyusun ulang rencananya. Rencananya jelas, Ia berencana untuk meledakkan server-server yang ada dan membuat sebanyak mungkin situs judi daring yang akan mati.&lt;/p&gt;
&lt;p&gt;Bantulah Bayu mencari berapa maksimal situs yang bisa Ia buat mati dengan menggunakan seminimal mungkin bom.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Input&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Baris pertama merupakan bilangan bulat &lt;strong&gt;N, M, K, dan L (1 ≤ N, K ≤ 2·105; 1 ≤ M ≤ N ; 0 ≤ L ≤ min(2·105, n·(n - 1) / 2))&lt;/strong&gt; yaitu masing-masing adalah banyaknya server, banyaknya lokasi server yang memiliki ahli penjinak bom, banyaknya bom yang dimiliki, dan banyaknya hubungan antar server.&lt;/li&gt;
&lt;li&gt;Baris kedua merupakan bilangan bulat &lt;strong&gt;V1, V2, ..., VN (1 ≤ Vi ≤ 109)&lt;/strong&gt; yaitu banyaknya situs yang menggunakan server &lt;em&gt;&lt;strong&gt;ke-i&lt;/strong&gt;&lt;/em&gt; &lt;strong&gt;(1 ≤ i ≤ N)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Baris ketiga adalah bilangan bulat &lt;em&gt;&lt;strong&gt;P1, P2, ..., PM&lt;/strong&gt;&lt;/em&gt; &lt;strong&gt;(1 ≤ Pi ≤ N)&lt;/strong&gt; yaitu lokasi server yang memiliki penjinak bom. Dipastikan nilai Pi akan berbeda.
&lt;strong&gt;L&lt;/strong&gt; baris berikutnya berisi dua buah bilangan bulat &lt;em&gt;aj&lt;/em&gt; dan &lt;em&gt;bj&lt;/em&gt; dipisahkan spasi &lt;strong&gt;(1 ≤ aj, bj ≤ N; aj ≠ bj)&lt;/strong&gt; artinya server &lt;em&gt;aj&lt;/em&gt; memiliki hubungan dengan server &lt;em&gt;bj&lt;/em&gt; dan sebaliknya. Dipastikan hubungan antara &lt;em&gt;aj&lt;/em&gt; dan &lt;em&gt;bj&lt;/em&gt; akan selalu berbeda untuk setiap baris &lt;em&gt;ke-j&lt;/em&gt; &lt;strong&gt;(1 ≤ j ≤ L)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Baris pertama merupakan bilangan bulat &lt;em&gt;x&lt;/em&gt; yaitu maksimal banyak situs yang bisa Bayu matikan.&lt;/li&gt;
&lt;li&gt;Baris kedua merupakan bilangan bulat &lt;em&gt;y&lt;/em&gt; yaitu minimal banyak bom yang digunakan untuk mendapatkan &lt;em&gt;x&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Input:
5 2 5 2
2 4 2 3 3
1 4
1 2
3 5

Output:
11
2
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;Input:
5 2 1 2
2 4 2 3 3
1 4
1 2
3 5

Output:
6
1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;
Pada tes pertama, Bayu bisa memilih untuk meledakkan server pada lokasi &lt;strong&gt;2, 3,&lt;/strong&gt; dan &lt;strong&gt;5&lt;/strong&gt;. Bayu dapat meledakkan server &lt;em&gt;ke-2&lt;/em&gt; sehingga server &lt;em&gt;ke-1&lt;/em&gt; juga mati dan membuat &lt;strong&gt;2 + 4 = 6&lt;/strong&gt; situs mati. Lalu, Bayu meledakkan server &lt;em&gt;ke-5&lt;/em&gt; dan membuat server &lt;em&gt;ke-3&lt;/em&gt; ikut mati dan membuat &lt;strong&gt;2 + 3 = 5&lt;/strong&gt; situs mati. Tidak ada lagi server yang dapat diledakkan sehingga maksimal situs yang mati adalah &lt;strong&gt;6 + 5 = 11&lt;/strong&gt; dengan menggunakan &lt;strong&gt;2&lt;/strong&gt; bom saja.&lt;/p&gt;
&lt;p&gt;Pada tes kedua, Bayu hanya memiliki satu bom. Sehingga, agar lebih banyak situs yang mati, Ia memilih meledakkan server &lt;em&gt;ke-2&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IPLEMENTASI 1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;

using namespace std;

#define int long long
#define fast ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);



signed main() {
    fast;;;

    int N, M, K, L;
    cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; M &amp;gt;&amp;gt; K &amp;gt;&amp;gt; L;

    vector &amp;lt; int &amp;gt; V(N + 1);
    for (int i = 1; i &amp;lt;= N; ++i) {
        cin &amp;gt;&amp;gt; V[i];
    }
    
    vector &amp;lt; bool &amp;gt; nope(N + 1, true);
    for (int i = 0; i &amp;lt; M; ++i) {
        int pi;
        cin &amp;gt;&amp;gt; pi;
        nope[pi] = false;
    }

    map &amp;lt; int, vector &amp;lt; int &amp;gt;&amp;gt; adj;
    for (int i = 0; i &amp;lt; L; ++i) {
        int a, b;
        cin &amp;gt;&amp;gt; a &amp;gt;&amp;gt; b;

        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    map &amp;lt; int, bool &amp;gt; visited;
    vector &amp;lt; int &amp;gt; component;

    for (int i = 1; i &amp;lt;= N; ++i) {
        if (!visited[i]) {
            int total = 0;
            bool bisa = false;
            stack &amp;lt; int &amp;gt; st;
            st.push(i);

            while (!st.empty()) {
                int u = st.top();
                st.pop();
                if (visited[u]) continue;
                visited[u] = true;
                total += V[u];
                if (nope[u]) bisa = true;

                for (int v: adj[u])
                    if (!visited[v]) st.push(v);
            }

            if (bisa) component.push_back(total);
        }
    }

    sort(component.rbegin(), component.rend());

    int meledak = 0;
    int bomb = 0;
    for (int i = 0; i &amp;lt; min(K, (int) component.size()); ++i) {
        meledak += component[i];
        bomb++;
    }

    cout &amp;lt;&amp;lt; meledak &amp;lt;&amp;lt; &apos;\n&apos; &amp;lt;&amp;lt; bomb &amp;lt;&amp;lt; &apos;\n&apos;;

    return 0;
}

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Definisi Rekayasa Perangkat Lunak (RPL)</title><link>https://tenzly-amirzaky.vercel.app/posts/rpl/</link><guid isPermaLink="true">https://tenzly-amirzaky.vercel.app/posts/rpl/</guid><description>Read more about Rekayasa Perangkat Lunak (RPL)</description><pubDate>Tue, 04 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;strong&gt;I N T R O&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Pernah nggak sih kamu kepikiran, kenapa aplikasi yang kita pakai sehari-hari—kayak Instagram, Tokopedia, atau Spotify—bisa berjalan dengan begitu mulus? Padahal, lebih dari 90% aplikasi gagal dalam tahun pertamanya karena kesalahan dalam pengembangan. Bayangin kalau aplikasi favoritmu tiba-tiba error, terus transaksi nggak bisa diproses, atau fitur pentingnya nggak berfungsi. Pasti nyebelin, kan? Nah, supaya hal itu nggak terjadi, ada satu bidang yang memastikan semuanya berjalan lancar yaitu Rekayasa Perangkat Lunak (RPL).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RPL itu apa sih?&lt;/strong&gt; Rekayasa Perangkat Lunak adalah disiplin ilmu yang berfokus pada pengembangan, perancangan, pengujian, dan pemeliharaan perangkat lunak agar dapat berfungsi secara efisien, dapat diandalkan, dan memenuhi kebutuhan pengguna.&lt;a href=&quot;https://kd-cibiru.upi.edu/index.php/component/content/article/pengenalan-rekayasa-perangkat-lunak-dasar-dasar-dan-penerapannya?catid=29&amp;amp;highlight=WyJwZW5nZW5hbGFuIiwicmVrYXlhc2EiLCJwZXJhbmdrYXQiLCJsdW5hayIsImRhc2FyLWRhc2FyIiwiZGFuIiwicGVuZXJhcGFubnlhIl0=&amp;amp;Itemid=101&quot;&gt;KD-CIBIRU.UPI.EDU&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;R E S E A R C H&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Menurut Roger S. Pressman(2005):&lt;a href=&quot;https://books.google.co.id/books?hl=en&amp;amp;lr=&amp;amp;id=bL7QZHtWvaUC&amp;amp;oi=fnd&amp;amp;pg=PA1&amp;amp;dq=Pressman,+R.+S.+(2005).+Software+Engineering:+A+Practitioner%27s+Approach.+McGraw-Hill.&amp;amp;ots=O9wfaRsN3n&amp;amp;sig=EIN4jB99hP9XOhqoBGSaeB0vSMk&amp;amp;redir_esc=y#v=onepage&amp;amp;q=Pressman%2C%20R.%20S.%20(2005).%20Software%20Engineering%3A%20A%20Practitioner&apos;s%20Approach.%20McGraw-Hill.&amp;amp;f=false&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(Dalam Bahasa Indonesia kira-kira) &quot;RPL adalah pendekatan disiplin untuk pengembangan, operasi, pemeliharaan, dan penghapusan perangkat lunak.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Menurut Ian Sommerville (2016):&lt;a href=&quot;https://ieeexplore.ieee.org/abstract/document/7420501&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(Dalam Bahasa Indonesia kira-kira) &quot;Perangkat lunak tidak hanya mencakup program, tetapi juga semua dokumentasi dan konfigurasi data yang berhubungan dan diperlukan untuk pengoperasian program yang benar.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Menurut itria Nur Hasanah (2021):&lt;a href=&quot;https://press.umsida.ac.id/index.php/umsidapress/article/view/978-623-6833-89-6&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Rekayasa perangkat lunak adalah disiplin yang membahas semua aspek produksi perangkat lunak, mulai dari tahap awal spesifikasi sistem sampai pemeliharaan sistem setelah digunakan.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dede Aldian Firmansyah et al. (2024):&lt;a href=&quot;https://jurnalmahasiswa.com/index.php/jriin/article/view/1350&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Rekayasa perangkat lunak mencakup berbagai teknologi. Untuk mencapai kualitas, banyak pendekatan teknis dan komitmen mendasar yang harus digunakan.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;serta Menurut Buku &quot;Rekayasa Perangkat Lunak(2024)&quot;&lt;a href=&quot;https://www.researchgate.net/publication/387225364_REKAYASA_PERANGKAT_LUNAK&quot;&gt;Source&lt;/a&gt; yang ditulis oleh:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ika Safitri Windiarti, ST., M.Eng., PhD
Purwita Sari, S.SI., M.Kom
Citra Amalia, ST., M.T
Dara Sawitri, ST., M.T
Safuan, S.Kom., M.Kom
M. Syahputra, S.Kom., M.Kom
Agung Yuliyanto Nugroho, S.Kom., M.Kom., M.Par
Novita Anggraini, S.Kom., M.Kom
Ir. Gde Brahupadhya Subiksa, S.Kom., M.T., IPM
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;dan di terbitkan oleh CV Bravo Press Indonesia&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;├── Analisis    : &quot;Dalam konsep analisis kebutuhan perangkat lunak, hal-hal yang perlu diperhatikan yaitu mengidentifikasi, mendefinisikan, mendokumentasikan kebutuhan pengguna serta stakeholder. Dokumentasi yang rinci memungkinkan tim pengembang memahami dengan jelas apa yang harus dibangun.&quot; (Bab 4 - Konsep Analisis Kebutuhan Perangkat Lunak) 
├── Design      : &quot;Model proses rekayasa perangkat lunak adalah kerangka kerja yang digunakan untuk merencanakan, mengorganisir, dan mengelola pengembangan perangkat lunak. Model ini menggambarkan tahapan mulai dari analisis kebutuhan hingga pemeliharaan.&quot; (Bab 2 - Model Proses Rekayasa Perangkat Lunak)
├── Coding      : &quot;Penggunaan Git dalam pengembangan perangkat lunak membantu pengembang dalam mengelola perubahan kode sumber secara kolaboratif. Git memudahkan pengembang dalam membangun fitur, memperbaiki bug, serta melacak perubahan kode dengan lebih efisien.&quot; (Bab 7 - Penggunaan Git)
├── Testing     : &quot;Proses pengujian perangkat lunak bertujuan untuk mendeteksi kesalahan sebelum perangkat lunak diterapkan. Teknik pengujian meliputi pengujian fungsionalitas, performa, serta kompatibilitas dengan sistem yang ada.&quot; (Bab 8 - Konsep Pemeliharaan Perangkat Lunak)
└── Maintenance : &quot;Pemeliharaan perangkat lunak merupakan tahapan yang memastikan sistem tetap berfungsi sesuai kebutuhan pengguna. Proses ini mencakup perbaikan bug, peningkatan fitur, serta adaptasi terhadap perubahan lingkungan teknologi.&quot; (Bab 8 - Konsep Pemeliharaan Perangkat Lunak)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;strong&gt;O P I N I&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;jadi.. bisa dibilang, Rekayasa Perangkat Lunak tuh adalah disiplin ilmu yang sangat penting dalam perkembangan dan pemeliharaan perangkat lunak. Prosesnya melibatkan beberapa tahap utama—Analisis, Desain, Coding, Testing, dan Maintenance—yang semuanya bertujuan untuk menghasilkan perangkat lunak yang berkualitas tinggi, cost-efficient, dan sesuai dengan kebutuhan pengguna.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;K E S I M P U L A N&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;So.. di dunia yang semakin terdigitalisasi ini, RPL tuh udah kayak bagian yang nggak bisa dipisahin dari perkembangan teknologi. Bayangin aja kalau nggak ada RPL, aplikasi yang kita pakai sehari-hari mungkin nggak bakal berjalan sebaik sekarang. Makanya, memahami dan menerapkan prinsip-prinsip RPL jadi penting banget, apalagi buat kamu yang tertarik di dunia teknologi.
Dengan ngerti gimana perangkat lunak dikembangkan dan dipelihara, kita jadi bisa lebih menghargai kerja keras di balik layar aplikasi yang kita pakai tiap hari.&lt;/p&gt;
&lt;p&gt;&amp;lt;!--
This blog template is built with &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. For the things that are not mentioned in this guide, you may find the answers in the &lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro Docs&lt;/a&gt;.
wadawda&lt;/p&gt;
&lt;h2&gt;Front-matter of Posts&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;---
title: My First Blog Post
published: 2023-09-09
description: This is the first post of my new Astro blog.
image: ./cover.jpg
tags: [Foo, Bar]
category: Front-end
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The title of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;published&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The date the post was published.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A short description of the post. Displayed on index page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The cover image path of the post.&amp;lt;br/&amp;gt;1. Start with &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;: Use web image&amp;lt;br/&amp;gt;2. Start with &lt;code&gt;/&lt;/code&gt;: For image in &lt;code&gt;public&lt;/code&gt; dir&amp;lt;br/&amp;gt;3. With none of the prefixes: Relative to the markdown file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The tags of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;category&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The category of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If this post is still a draft, which won&apos;t be displayed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Where to Place the Post Files&lt;/h2&gt;
&lt;p&gt;Your post files should be placed in &lt;code&gt;src/content/posts/&lt;/code&gt; directory. You can also create sub-directories to better organize your posts and assets.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/content/posts/
├── post-1.md
└── post-2/
    ├── cover.png
    └── index.md
``` --&amp;gt;&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Media Include in the Posts</title><link>https://tenzly-amirzaky.vercel.app/posts/video/</link><guid isPermaLink="true">https://tenzly-amirzaky.vercel.app/posts/video/</guid><description>This post demonstrates that can be embedded in a WEB.</description><pubDate>Mon, 03 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;DEMO&lt;/h2&gt;
&lt;p&gt;Media embedded showcase page for Tenzly personal Website.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: Tenzly Demo Media
published: 2025-02-03
// ...
---

&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Music&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe
src=&quot;https://widget.qobuz.com/playlist/27666113?zone=US-en&amp;amp;display=compact&quot;
width=&quot;100%&quot;
height=&quot;107&quot;
&amp;gt;
&amp;lt;p&amp;gt;Your browser does not support iframes.&amp;lt;/p&amp;gt;
&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe style=&quot;border-radius:12px&quot; src=&quot;https://open.spotify.com/embed/playlist/4dWNwprwz8Q2idT9yQ7iA2?utm_source=generator&quot; width=&quot;100%&quot; height=&quot;460&quot; frameBorder=&quot;0&quot; allowfullscreen=&quot;&quot; allow=&quot;autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture&quot; loading=&quot;lazy&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h2&gt;YouTube&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/S2Xu6_XWy4M?si=P2GpnfsbCHVSQ6or&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h2&gt;Bilibili&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?bvid=BV1fK4y1s7Qf&amp;amp;p=1&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt; &amp;lt;/iframe&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Simple Guides for This WEB</title><link>https://tenzly-amirzaky.vercel.app/posts/guide/</link><guid isPermaLink="true">https://tenzly-amirzaky.vercel.app/posts/guide/</guid><description>How to use this blog template.</description><pubDate>Mon, 03 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This Website is built with &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. For Project showcase or assignment collection of &lt;strong&gt;Tenzly&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Front-matter of Posts&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;---
title: The Tenzly Personal Website
published: 2025-02-03
description: This is the first My Personal WEB, build with Astro.
image: ./cover.jpg
tags: [Foo, Bar]
category: Front-end
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The title of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;published&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The date the post was published.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A short description of the post. Displayed at index page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The cover image path of the post.&amp;lt;br/&amp;gt;1. Start with &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;: Use web image&amp;lt;br/&amp;gt;2. Start with &lt;code&gt;/&lt;/code&gt;: For image in &lt;code&gt;public&lt;/code&gt; dir&amp;lt;br/&amp;gt;3. With none of the prefixes: Relative to the markdown file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The tags of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;category&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The category of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If this post is still a draft, which won&apos;t be displayed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Where to Place the Post Files&lt;/h2&gt;
&lt;p&gt;Your post files should be placed in &lt;code&gt;Home/posts&lt;/code&gt; directory. You can also create sub-directories to better organize your posts and assets.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Home/posts/
├── post-1
└── post-2/
    ├── cover.png
    └── index.md
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item></channel></rss>