Masalalarning video ko'rinishidagi yechimini quyidagi havola orqali o'rganishingiz mumkin:
https://youtu.be/sujESTnQIHY
A. MP3 Player
\(d = |a-b|\) bo'lsin. Ko'rinib turibdiki \(N\) juft bo'lsa javob \(N \over 2\), aks holda \(\lfloor{N+1 \over 2} \rfloor\)ga teng.
a = int(input())
b = int(input())
d = abs(a - b)
print((d + 1) // 2)
B. Tubga bo'linmas
Chegaralar kichkinaligi uchun har bir javoblarni tekshirib chiqish yetarli. Chiroyliroq yechim qidiruvchilar esa javob \(N+1\)-tub songa teng ekanini sezishgan bo'lsa kerak.
n = int(input())
n += 1
x = 1
while n > 0:
x += 1
prime = True
for d in range(2, x):
if x % d == 0:
prime = False
break
if prime:
n -= 1
print(x)
C. Olma uzish
O'zidan boshqa hammaga olma berishni, faqat o'zidan bitta olma olib qo'yish deb tushunish mumkin. Demak javob \(\sum(A_i-\min{A}) = \sum{A_i} - N \cdot \min{A}\)ga teng.
n = int(input())
a = list(map(int, input().split()))
print(sum(a) - n * min(a))
D. Binar satr
Javobning maksimal qiymatini topib ko'raylik. Jami qismsatrlar soni \(N(N+1) \over 2\)ga teng. Dirixle prinsipiga ko'ra, javob shu sondan katta bo'la olmaydi. \(N = 2 \cdot 10^5\) holatda \(\approx 2 \cdot 10^{10} \approx 2^{35}\). \(F\) funksiya eksponentsial bo'lgani uchun, har bir \(L\) uchun 35ta \(R\)larni qarash yetarli, chunki undan katta \(R\)lar bizga qiziq emas.
Complexity: \(O(N \log^2{N})\) yoki \(O(N \log{N})\).
Bonus: Javob \(2N\)dan oshmasligini isbotlang.
#include <bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
string s;
cin >> s;
int n = (int) s.size();
const long long LIM = 2e10 + 5;
set<long long> values;
for (int i = 0; i < n; i++){
if (s[i] == '0') {
values.insert(0);
continue;
}
long long x = 1;
values.insert(1);
int j = i + 1;
while (j < n && x <= LIM){
x = x * 2 + (s[j] - '0');
values.insert(x);
j++;
}
}
long long mex = 0;
while (values.find(mex) != values.end()) mex++;
cout << mex << endl;
return 0;
}
E. Mamlakatlar va shaharlar
\(L_x\) bu \(x\)-shahardan eng chapdagi shahargacha (shu mamlakatdagi) borish kombinatsiyalari bo'lsin. Xuddi shunday, \(R_x\) eng o'ngdagi shahargacha kombinatsiyalar soni. Shuningdek, \(F_i\) bu \(i\)-mamlakatda eng chapdagi shahardan eng o'ngdagi shahargacha borish usullari soni. Bularning barchasini BFS (breadth-first-search) va DP (dynamic programming) yordamida hisoblab chiqish mumkin.
Javob esa \(R_X \cdot F_{i+1} \cdot ... \cdot F_{j-1} \cdot L_Y\)ga teng, bunda \(i\) va \(j\) mos ravishda \(X\) va \(Y\)-shaharlar joylashgan mamlakat. Oraliqda ko'paytmani hisoblash uchun prefiks massivlar va sonni teskiri modulini topish yordam berishi mumkin.
Complexity: \(O(N\log{N} + Q \log{\rm{MOD}})\) yoki \(O((N+Q)\log{N})\).
Bonus: xuddi shu masalani modul murakkab son holat uchun ishlang.
C++:
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
int inv(int x) {
return x <= 1 ? x : MOD - (long long)(MOD / x) * inv(MOD % x) % MOD;
}
int main(){
ios_base::sync_with_stdio(false);
int k, n, m;
cin >> k >> n >> m;
vector<int> lp(k), rp(k); // left_point, right_point
vector<int> where(n);
for (int i = 0; i < k; i++){
int x; cin >> x;
if (i) lp[i] = rp[i - 1] + 1;
rp[i] = lp[i] + x - 1;
for (int j = lp[i]; j <= rp[i]; j++) where[j] = i;
}
vector<vector<int>> g(n);
for (int i = 0; i + 1 < n; i++){
g[i].push_back(i + 1);
g[i + 1].push_back(i);
}
while (m--){
int u, v;
cin >> u >> v;
--u, --v;
g[u].push_back(v);
g[v].push_back(u);
}
auto bfs = [&](int start, int l, int r) -> vector<int>{
vector<int> d(r - l + 1, 1e9);
vector<int> ways(r - l + 1, 0);
d[start - l] = 0;
ways[start - l] = 1;
queue<int> q;
q.push(start);
while (!q.empty()){
int v = q.front();
q.pop();
for (int u : g[v]){
if (u < l || u > r) continue;
if (d[u - l] == 1e9){
d[u - l] = d[v - l] + 1;
q.push(u);
}
if (d[u - l] + 1 == d[v - l]){
ways[v - l] += ways[u - l];
ways[v - l] %= MOD;
}
}
}
return ways;
};
vector<vector<int>> ways_left, ways_right;
vector<long long> pref(k);
for (int i = 0; i < k; i++){
vector<int> wl = bfs(lp[i], lp[i], rp[i]);
vector<int> wr = bfs(rp[i], lp[i], rp[i]);
ways_left.push_back(wl);
ways_right.push_back(wr);
pref[i] = wl.back();
if (i){
pref[i] *= pref[i - 1];
pref[i] %= MOD;
}
}
int q;
cin >> q;
while (q--){
int x, y;
cin >> x >> y;
--x, --y;
if (x > y) swap(x, y);
int i = where[x], j = where[y];
long long ans = ways_right[i][x - lp[i]] * ways_left[j][y - lp[j]] % MOD;
if (i + 1 < j) {
long long middle = pref[j - 1] * inv(pref[i]) % MOD;
ans *= middle % MOD;
ans %= MOD;
}
cout << ans << endl;
}
return 0;
}
.