#include <bits/stdc++.h>
using namespace std;
int main() {
// Complexity - Big O
// Seberapa banyak operasi yg dilakukan/runtime berubah
// saat ada perubahan input
// contoh: bubble sort vs quick sort
/*
int n, data[1000001]; // O(1)
cin >> n; // O(1)
for(int i = 0; i < n; i++) // O(n)
cin >> data[i];
for(int i = 0; i < n; i++) // O(n^2)
for(int j = 1; j < n; j++)
if(data[j] < data[j-1]) {
int tmp = data[j];
data[j] = data[j-1];
data[j-1] = tmp;
}
n = 10 -> op = 1+1+10+90 = 102
n = 100 -> op = 1+1+100+9900 = 10002
n = n -> op ~ n^2 -> O(n^2)
*/
// Rule of Thumb: 10^8 op = 1s
// Big O = O(n^2)
/*
O(n)
n = 10 -> rt = 1ms
n = 100 -> rt = 10ms
n = 1000 -> rt = 100ms
..
O(n^2)
n = 10 -> rt = 1ms
n = 100 -> rt = 100ms
n = 1000000 -> rt = 10^10ms
*/
// 4 Paradigm overview
/*
// n <= 200000, data[i] <= 10^6
int data = {10, 7, 3, 5, 8, 6, 9, 11}, n = 8;
// ^ ^ ^ ^
// 3, 5, 8, 9
// 1. Cari bilangan terbesar & terkecil dari array data. O(n)
maks = data[0];
for(int i = 1; i < n; i++)
if(data[i] > maks)
maks = data[i];
// 2. Cari bilangan terbesar urutan ke-k dari array data. (k<=n)
// Pendekatan pertama: sort O(n^2) -> Time Limit Exceeded
// Pendekatan kedua: Cari bil terbesar, lalu hapus.
// Cari bil kedua terbesar, lalu hapus.
// Ulangi sampai bil ke-(k-1) terbesar & hapus.
// Cari bil ke-k terbesar. -> O(n*k) = O(n^2)
for(int i = 0; i < k; i++)
for(int j = 0; j < n; j++)
...
// Pendekatan yang tepat: sort O(n log n)
// 3. Cari selisih terbesar dalam array data.
// Pendekatan complete search -> O(n^2) -> TLE
for(int i = 0; i < n; i++)
for(int j = i+1; j < n; j++)
if(maks < abs(data[i]-data[j]))
maks = abs(data[i]-data[j]);
// loop = (n-1)+(n-2)+...+1+0 = n*(n-1)/2 = (n^2-n)/2
// Greedy -> O(n)
// 4. Cari panjang LIS = Longest Increasing Subsequence di array data.
// Dynamic Programming
// - banyak subsoal yang overlap, yang seharusnya bisa dikerjakan
// sekali saja
// 9! = 362880
// 10! = 362880*10 = 3628800
// 11! = 3628800*11 = 39916800
// teknik memoization
*/
// Complete Search
// Iterative = loop
// Recursive = fungsi rekursif
// Pruning -> tidak melanjutkan proses yang pasti gagal
/* 8 ratu di papan catur -> 8 Queens problem
o..o..o.
.o.o.o..
..ooo...
oooQoooo
..ooo...
.o.o.o..
o..o..o.
...o...o
C(64, 8) = terlalu besar
1.......
..2.....
> ....3...
........
........
........
........
........
8^7
*/
/*
// Divide & Conquer -> harus terurut
// linear search -> per langkah -1 -> O(n)
// binary search -> per langkah /2 -> O(log n)
// Soal: cari sebuah nilai dalam array yg terurut
// cari = 10
// {1, 1, 2, 2, 2, 4, 5, 6, 6, 9, 10, 13, 17, 22, 23}
// |-------------------------------------|
// data terurut: i1 <= i2 -> data[i1] <= data[i2]
int data[] = {1, 1, 2, 2, 2, 4, 5, 6, 6, 9, 10, 13, 17, 22, 23}, n = 15;
int cari = 10;
// linear search
for(int i = 0; i < n; i++)
if(data[i] == cari)
cout << cari << " ditemukan di index " << i << endl;
// binary search
// {1, 1, 2, 2, 2, 4, 5, 6, 6, 9, 10, 13, 17, 22, 23}
// |--------------------|-------------------------|
// |----------|-----------|
// |--|---|
// |
// dalam 1 langkah -> search space berkurang jadi 1/2 nya
// dalam x langkah -> search space berkurang jadi 1/2^x nya
// n = 2^x -> x = log2 n
// ukuran search space = n -> banyak langkah = log2 n = log n
int lo = 0, hi = n-1, mid;
while(lo < hi) {
mid = (lo+hi)/2;
if(data[mid] > cari)
hi = mid-1;
else if(data[mid] < cari)
lo = mid+1;
else
lo = hi = mid;
}
cout << cari << " ditemukan di index: " << lo << endl;
*/
/*
// Bisection method / Binary Search The Answer (BSTA)
// 0 <= x < PI/2, sin(x) = increasing
// x1 < x2 -> sin(x1) < sin(x2)
// sin(x) = 0.75 -> x = arcsin(0.75)
double PI = acos(-1);
// cos(180) = cos(PI) = -1
// acos(-1) = PI
double y = 0.75;
double lo = 0, hi = PI/2, mid;
while(hi-lo > 1e-12) { // 1.23e-4 = 1.23*10^-4
mid = (lo+hi)/2;
cout << lo << " " << mid << " " << hi << endl;
if(sin(mid) > y)
hi = mid;
else if(sin(mid) < y)
lo = mid;
}
cout << "arcsin(" << y << ") = " << lo << endl;
*/
// Greedy
// Lihat contoh di PKD
// Dynamic Programming
// N = a_k + a_i_2 + ... + a_i_m -> m minimal = f(N)
// (N-a_k) = a_i_2 + ... + a_i_m -> m minimal = f(N-a_k)
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgppbnQgbWFpbigpIHsKCS8vIENvbXBsZXhpdHkgLSBCaWcgTwoJLy8gU2ViZXJhcGEgYmFueWFrIG9wZXJhc2kgeWcgZGlsYWt1a2FuL3J1bnRpbWUgYmVydWJhaAoJLy8gICBzYWF0IGFkYSBwZXJ1YmFoYW4gaW5wdXQKCS8vIGNvbnRvaDogYnViYmxlIHNvcnQgdnMgcXVpY2sgc29ydAoJLyoKCWludCBuLCBkYXRhWzEwMDAwMDFdOwkJCQkJLy8gTygxKQoJY2luID4+IG47CQkJCQkJCQkvLyBPKDEpCglmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQkJCQkvLyBPKG4pCgkJY2luID4+IGRhdGFbaV07Cglmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQkJCQkvLyBPKG5eMikKCQlmb3IoaW50IGogPSAxOyBqIDwgbjsgaisrKQoJCQlpZihkYXRhW2pdIDwgZGF0YVtqLTFdKSB7CgkJCQlpbnQgdG1wID0gZGF0YVtqXTsKCQkJCWRhdGFbal0gPSBkYXRhW2otMV07CgkJCQlkYXRhW2otMV0gPSB0bXA7CgkJCX0KCW4gPSAxMCAtPiBvcCA9IDErMSsxMCs5MCA9IDEwMgoJbiA9IDEwMCAtPiBvcCA9IDErMSsxMDArOTkwMCA9IDEwMDAyCgluID0gbiAtPiBvcCB+IG5eMiAtPiBPKG5eMikKCSovCgkvLyBSdWxlIG9mIFRodW1iOiAxMF44IG9wID0gMXMKCS8vIEJpZyBPID0gTyhuXjIpCgkvKgoJTyhuKQoJbiA9IDEwIC0+IHJ0ID0gMW1zCgluID0gMTAwIC0+IHJ0ID0gMTBtcwoJbiA9IDEwMDAgLT4gcnQgPSAxMDBtcwoJLi4KCQoJTyhuXjIpCgluID0gMTAgLT4gcnQgPSAxbXMKCW4gPSAxMDAgLT4gcnQgPSAxMDBtcwoJbiA9IDEwMDAwMDAgLT4gcnQgPSAxMF4xMG1zCgkqLwoJCgkvLyA0IFBhcmFkaWdtIG92ZXJ2aWV3CgkvKgoJLy8gbiA8PSAyMDAwMDAsIGRhdGFbaV0gPD0gMTBeNgoJaW50IGRhdGEgPSB7MTAsIDcsIDMsIDUsIDgsIDYsIDksIDExfSwgbiA9IDg7CgkvLyAgICAgICAgICAgICAgICAgXiAgXiAgXiAgICAgXiAgIAoJLy8gMywgNSwgOCwgOQoJCgkvLyAxLiBDYXJpIGJpbGFuZ2FuIHRlcmJlc2FyICYgdGVya2VjaWwgZGFyaSBhcnJheSBkYXRhLiBPKG4pCgltYWtzID0gZGF0YVswXTsKCWZvcihpbnQgaSA9IDE7IGkgPCBuOyBpKyspCgkJaWYoZGF0YVtpXSA+IG1ha3MpCgkJCW1ha3MgPSBkYXRhW2ldOwoJLy8gMi4gQ2FyaSBiaWxhbmdhbiB0ZXJiZXNhciB1cnV0YW4ga2UtayBkYXJpIGFycmF5IGRhdGEuIChrPD1uKQoJLy8gUGVuZGVrYXRhbiBwZXJ0YW1hOiBzb3J0IE8obl4yKSAtPiBUaW1lIExpbWl0IEV4Y2VlZGVkCgkvLyBQZW5kZWthdGFuIGtlZHVhOiBDYXJpIGJpbCB0ZXJiZXNhciwgbGFsdSBoYXB1cy4KCS8vICAgICAgICAgICAgICAgICAgIENhcmkgYmlsIGtlZHVhIHRlcmJlc2FyLCBsYWx1IGhhcHVzLgoJLy8gICAgICAgICAgICAgICAgICAgVWxhbmdpIHNhbXBhaSBiaWwga2UtKGstMSkgdGVyYmVzYXIgJiBoYXB1cy4KCS8vICAgICAgICAgICAgICAgICAgIENhcmkgYmlsIGtlLWsgdGVyYmVzYXIuIC0+IE8obiprKSA9IE8obl4yKQoJZm9yKGludCBpID0gMDsgaSA8IGs7IGkrKykKCQlmb3IoaW50IGogPSAwOyBqIDwgbjsgaisrKQoJCQkuLi4KCS8vIFBlbmRla2F0YW4geWFuZyB0ZXBhdDogc29ydCBPKG4gbG9nIG4pCgkvLyAzLiBDYXJpIHNlbGlzaWggdGVyYmVzYXIgZGFsYW0gYXJyYXkgZGF0YS4KCS8vIFBlbmRla2F0YW4gY29tcGxldGUgc2VhcmNoIC0+IE8obl4yKSAtPiBUTEUKCWZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspCgkJZm9yKGludCBqID0gaSsxOyBqIDwgbjsgaisrKQoJCQlpZihtYWtzIDwgYWJzKGRhdGFbaV0tZGF0YVtqXSkpCgkJCQltYWtzID0gYWJzKGRhdGFbaV0tZGF0YVtqXSk7CgkvLyBsb29wID0gKG4tMSkrKG4tMikrLi4uKzErMCA9IG4qKG4tMSkvMiA9IChuXjItbikvMgoJLy8gR3JlZWR5IC0+IE8obikKCS8vIDQuIENhcmkgcGFuamFuZyBMSVMgPSBMb25nZXN0IEluY3JlYXNpbmcgU3Vic2VxdWVuY2UgZGkgYXJyYXkgZGF0YS4KCS8vIER5bmFtaWMgUHJvZ3JhbW1pbmcKCS8vIC0gYmFueWFrIHN1YnNvYWwgeWFuZyBvdmVybGFwLCB5YW5nIHNlaGFydXNueWEgYmlzYSBkaWtlcmpha2FuCgkvLyAgIHNla2FsaSBzYWphCgkvLyA5ISA9IDM2Mjg4MAoJLy8gMTAhID0gMzYyODgwKjEwID0gMzYyODgwMAoJLy8gMTEhID0gMzYyODgwMCoxMSA9IDM5OTE2ODAwCgkvLyB0ZWtuaWsgbWVtb2l6YXRpb24KCSovCgkKCS8vIENvbXBsZXRlIFNlYXJjaAoJLy8gSXRlcmF0aXZlID0gbG9vcAoJLy8gUmVjdXJzaXZlID0gZnVuZ3NpIHJla3Vyc2lmCgkvLyBQcnVuaW5nIC0+IHRpZGFrIG1lbGFuanV0a2FuIHByb3NlcyB5YW5nIHBhc3RpIGdhZ2FsCgkvKiA4IHJhdHUgZGkgcGFwYW4gY2F0dXIgLT4gOCBRdWVlbnMgcHJvYmxlbQoJby4uby4uby4KCS5vLm8uby4uCgkuLm9vby4uLgoJb29vUW9vb28KCS4ub29vLi4uCgkuby5vLm8uLgoJby4uby4uby4KCS4uLm8uLi5vCgkKCUMoNjQsIDgpID0gdGVybGFsdSBiZXNhcgoJCgkxLi4uLi4uLgoJLi4yLi4uLi4KPgkuLi4uMy4uLgoJLi4uLi4uLi4KCS4uLi4uLi4uCgkuLi4uLi4uLgoJLi4uLi4uLi4KCS4uLi4uLi4uCgk4XjcKCSovCgkKCS8qCgkvLyBEaXZpZGUgJiBDb25xdWVyIC0+IGhhcnVzIHRlcnVydXQKCS8vIGxpbmVhciBzZWFyY2ggLT4gcGVyIGxhbmdrYWggLTEgLT4gTyhuKQoJLy8gYmluYXJ5IHNlYXJjaCAtPiBwZXIgbGFuZ2thaCAvMiAtPiBPKGxvZyBuKQoJCgkvLyBTb2FsOiBjYXJpIHNlYnVhaCBuaWxhaSBkYWxhbSBhcnJheSB5ZyB0ZXJ1cnV0CgkvLyBjYXJpID0gMTAKCS8vIHsxLCAxLCAyLCAyLCAyLCA0LCA1LCA2LCA2LCA5LCAxMCwgMTMsIDE3LCAyMiwgMjN9CgkvLyAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CgkvLyBkYXRhIHRlcnVydXQ6IGkxIDw9IGkyIC0+IGRhdGFbaTFdIDw9IGRhdGFbaTJdCglpbnQgZGF0YVtdID0gezEsIDEsIDIsIDIsIDIsIDQsIDUsIDYsIDYsIDksIDEwLCAxMywgMTcsIDIyLCAyM30sIG4gPSAxNTsKCWludCBjYXJpID0gMTA7CgkKCS8vIGxpbmVhciBzZWFyY2gKCWZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspCgkJaWYoZGF0YVtpXSA9PSBjYXJpKQoJCQljb3V0IDw8IGNhcmkgPDwgIiBkaXRlbXVrYW4gZGkgaW5kZXggIiA8PCBpIDw8IGVuZGw7CgkKCS8vIGJpbmFyeSBzZWFyY2gKCS8vIHsxLCAxLCAyLCAyLCAyLCA0LCA1LCA2LCA2LCA5LCAxMCwgMTMsIDE3LCAyMiwgMjN9CgkvLyAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CgkvLyAgICAgICAgICAgICAgICAgICAgICAgICAgfC0tLS0tLS0tLS18LS0tLS0tLS0tLS18CgkvLyAgICAgICAgICAgICAgICAgICAgICAgICAgfC0tfC0tLXwKCS8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAoJLy8gZGFsYW0gMSBsYW5na2FoIC0+IHNlYXJjaCBzcGFjZSBiZXJrdXJhbmcgamFkaSAxLzIgbnlhCgkvLyBkYWxhbSB4IGxhbmdrYWggLT4gc2VhcmNoIHNwYWNlIGJlcmt1cmFuZyBqYWRpIDEvMl54IG55YQoJLy8gbiA9IDJeeCAtPiB4ID0gbG9nMiBuCgkvLyB1a3VyYW4gc2VhcmNoIHNwYWNlID0gbiAtPiBiYW55YWsgbGFuZ2thaCA9IGxvZzIgbiA9IGxvZyBuCglpbnQgbG8gPSAwLCBoaSA9IG4tMSwgbWlkOwoJd2hpbGUobG8gPCBoaSkgewoJCW1pZCA9IChsbytoaSkvMjsKCQlpZihkYXRhW21pZF0gPiBjYXJpKQoJCQloaSA9IG1pZC0xOwoJCWVsc2UgaWYoZGF0YVttaWRdIDwgY2FyaSkKCQkJbG8gPSBtaWQrMTsKCQllbHNlCgkJCWxvID0gaGkgPSBtaWQ7Cgl9Cgljb3V0IDw8IGNhcmkgPDwgIiBkaXRlbXVrYW4gZGkgaW5kZXg6ICIgPDwgbG8gPDwgZW5kbDsKCSovCgkKCS8qCgkvLyBCaXNlY3Rpb24gbWV0aG9kIC8gQmluYXJ5IFNlYXJjaCBUaGUgQW5zd2VyIChCU1RBKQoJLy8gMCA8PSB4IDwgUEkvMiwgc2luKHgpID0gaW5jcmVhc2luZwoJLy8geDEgPCB4MiAtPiBzaW4oeDEpIDwgc2luKHgyKQoJLy8gc2luKHgpID0gMC43NSAtPiB4ID0gYXJjc2luKDAuNzUpCglkb3VibGUgUEkgPSBhY29zKC0xKTsKCS8vIGNvcygxODApID0gY29zKFBJKSA9IC0xCgkvLyBhY29zKC0xKSA9IFBJCgkKCWRvdWJsZSB5ID0gMC43NTsKCWRvdWJsZSBsbyA9IDAsIGhpID0gUEkvMiwgbWlkOwoJd2hpbGUoaGktbG8gPiAxZS0xMikgewkvLyAxLjIzZS00ID0gMS4yMyoxMF4tNAoJCW1pZCA9IChsbytoaSkvMjsKCQljb3V0IDw8IGxvIDw8ICIgIiA8PCBtaWQgPDwgIiAiIDw8IGhpIDw8IGVuZGw7CgkJaWYoc2luKG1pZCkgPiB5KQoJCQloaSA9IG1pZDsKCQllbHNlIGlmKHNpbihtaWQpIDwgeSkKCQkJbG8gPSBtaWQ7Cgl9Cgljb3V0IDw8ICJhcmNzaW4oIiA8PCB5IDw8ICIpID0gIiA8PCBsbyA8PCBlbmRsOwoJKi8KCQoJLy8gR3JlZWR5CgkvLyBMaWhhdCBjb250b2ggZGkgUEtECgkKCS8vIER5bmFtaWMgUHJvZ3JhbW1pbmcKCS8vIE4gPSBhX2sgKyBhX2lfMiArIC4uLiArIGFfaV9tIC0+IG0gbWluaW1hbCA9IGYoTikKCS8vIChOLWFfaykgPSBhX2lfMiArIC4uLiArIGFfaV9tIC0+IG0gbWluaW1hbCA9IGYoTi1hX2spCgkKCXJldHVybiAwOwp9