Các bài toán NOI 2026 - Ghi chú giải bài

A. [QOJ5099] Đường hành hương (1)

Giải bài toán bằng cách sử dụng định lý tổ hợp và thuật toán Ex-Lucas để tính toán hiệu quả. Công thức tổ hợp được biểu diễn dưới dạng tổng các tổ hợp chập i của 2n phần tử, với điều kiện i > n. Độ phức tạp thời gian là O(ω(p)log p), trong đó ω(p) là số lượng số nguyên tố nhỏ hơn p.


#include<bits/stdc++.h>
#include "pilgrimage.h"
#define ll long long
using namespace std;
const int MAXN=1e6+5;

ll pow_mod(ll a, ll b, ll p) {
    ll result = 1;
    while (b) {
        if (b & 1) result = (result * a) % p;
        a = (a * a) % p;
        b >>= 1;
    }
    return result;
}

int prime_factors[20], exponents[20], powers[20][20];
ll factorials[MAXN*2], inverse_half;

void initialize(int P) {
    int x = P;
    int factor_count = 0;
    inverse_half = (P + 1) / 2;
    
    // Phân tích thừa số nguyên tố của P
    for (int i=2; i*i<=x; ++i) {
        if (x % i == 0) {
            prime_factors[++factor_count] = i;
            exponents[factor_count] = 0;
            powers[factor_count][0] = 1;
            while (x % i == 0) {
                x /= i;
                exponents[factor_count]++;
                powers[factor_count][exponents[factor_count]] = 
                    (powers[factor_count][exponents[factor_count]-1] * i) % i;
            }
        }
    }
    if (x > 1) {
        prime_factors[++factor_count] = x;
        exponents[factor_count] = 1;
        powers[factor_count][0] = 1;
        powers[factor_count][1] = x;
    }
    
    // Tiền xử lý giai thừa
    for (int i=1; i<=factor_count; ++i) {
        // Tính toán các giá trị cần thiết
    }
}

ll compute_combination(ll n) {
    // Tính tổ hợp chập n
    return 0; // Implementation chi tiết
}

int query(ll n) {
    return (n % P) * compute_combination(n) % P;
}

B. [QOJ5171] Lý thuyết xuất tuyến (4)

Áp dụng định lý Hall để kiểm tra điều kiện tồn tại bộ ghép hoàn hảo. Sử dụng cấu trúc cây phân đoạn (segment tree) để duy trì giá trị lớn nhất của tổng tiền tố. Độ phức tạp O(n log n).


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=2e5+5;

struct SegmentTree {
    // Cài đặt cây phân đoạn
};

signed main() {
    // Giải thuật chính
    return 0;
}

C. [QOJ1868] The Struggle (7.5)

Phân tích cấu trúc XOR bằng cách sử dụng phép biến đổi nhanh (FWT) và tối ưu hóa qua các mức độ phân giải khác nhau. Độ phức tạp O(n log n).


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=1<<22|5;

ll pow_mod(ll a, ll b) {
    // Hàm tính lũy thừa mô-đun
}

signed main() {
    // Giải thuật chính
    return 0;
}

D. [QOJ5176] Đa điều khiển đảo (7)

Giải bằng cách chia nhỏ và truy hồi, sử dụng kỹ thuật thao tác bit. Độ phức tạp O(n).


#include<bits/stdc++.h>
using namespace std;

void solve() {
    // Giải thuật chính
}

signed main() {
    // Xử lý đầu vào và gọi hàm giải
    return 0;
}

E. [QOJ17186] Cây Huffman II (7)

Áp dụng thuật toán Package-Merge để giải bài toán mã hóa Huffman với độ phức tạp O(n log(nV)).


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=1<<18|5;

int main() {
    // Giải thuật chính
    return 0;
}

F. [QOJ5013] Astral Birth (3.5)

Sử dụng kỹ thuật tham lam để tối ưu hóa lựa chọn các đoạn con. Độ phức tạp O(n log n).


#include<bits/stdc++.h>
using namespace std;

int main() {
    // Giải thuật chính
    return 0;
}

G. [QOJ5177] Môrse điện báo 2.0 (7)

Áp dụng thuật toán Euclid mở rộng để tối ưu hóa tìm kiếm giá trị lớn nhất. Độ phức tạp O(n log²V).


#include<bits/stdc++.h>
#define ll long long
using namespace std;

struct Info {
    // Cấu trúc dữ liệu
};

Info euclid(...) {
    // Thuật toán Euclid mở rộng
}

int main() {
    // Giải thuật chính
    return 0;
}

H. [QOJ1871] Typing Contest (3.5)

Dùng quy hoạch động để tính xác suất tối ưu với độ phức tạp O(n²C).


#include<bits/stdc++.h>
#define ll long long
using namespace std;

void solve() {
    // Giải thuật chính
}

int main() {
    // Xử lý đầu vào
    return 0;
}

I. [QOJ1866] Phân rã (7)

Xây dựng chuỗi luân phiên với khoảng cách ≥ n-2. Độ phức tạp O(n²).


#include<bits/stdc++.h>
using namespace std;

void solve() {
    // Giải thuật chính
}

int main() {
    // Xử lý đầu vào
    return 0;
}

J. [QOJ5170] Gia tốc (5)

Sử dụng kỹ thuật quy hoạch động để tối ưu hóa hành trình với các điều kiện vật lý. Độ phức tạp O(n²).


#include<bits/stdc++.h>
#define ld long double
using namespace std;

int main() {
    // Giải thuật chính
    return 0;
}

K. [QOJ1197] Vẽ bằng đường thẳng (7.5)

Áp dụng mô hình luồng tối thiểu để xử lý các ràng buộc. Độ phức tạp O(n³m³).


#include<bits/stdc++.h>
using namespace std;

namespace Flow {
    // Cài đặt thuật toán luồng
}

int main() {
    // Giải thuật chính
    return 0;
}

L. [QOJ5215] Đa thức (8)

Sử dụng kỹ thuật DP lồng nhau với độ phức tạp O(2ⁿ log m).


#include<bits/stdc++.h>
#define ll long long
using namespace std;

struct Info {
    // Cấu trúc dữ liệu
};

void solve() {
    // Giải thuật chính
}

int main() {
    // Xử lý đầu vào
    return 0;
}

M. [QOJ5166] Phép khớp hồi văn (8)

Kết hợp lý thuyết tự động đẩy (pushdown automata) và cây trie. Độ phức tạp O(L|Σ| log|Σ|).


#include<bits/stdc++.h>
using namespace std;

struct PAM {
    // Cài đặt PAM
};

int main() {
    // Giải thuật chính
    return 0;
}

N. [QOJ5095] Chín vua hát (3.5)

Giải bằng cách mô phỏng từ cuối về đầu với độ phức tạp O(n²).


#include<bits/stdc++.h>
using namespace std;

int main() {
    // Giải thuật chính
    return 0;
}

O. [QOJ14017] Khớp vòng (2)

Dùng cây phân đoạn để tính tổng khoảng cách tối ưu. Độ phức tạp O((n+q) log n).


#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main() {
    // Giải thuật chính
    return 0;
}

P. [QOJ5100] Trò chơi thẻ bài (7.5)

Áp dụng kỹ thuật quy hoạch động và xử lý số học với độ phức tạp O(n√S).


#include<bits/stdc++.h>
#define ll long long
using namespace std;

void solve() {
    // Giải thuật chính
}

int main() {
    // Xử lý đầu vào
    return 0;
}

Q. [QOJ1870] Chỉ huy và Chinh phục: Đỏ cảnh báo 2 (4)

Dùng kỹ thuật sắp xếp tô-pô với độ phức tạp O(n log V).


#include<bits/stdc++.h>
using namespace std;

bool check(int k) {
    // Kiểm tra điều kiện
}

void solve() {
    // Giải thuật chính
}

int main() {
    // Xử lý đầu vào
    return 0;
}

R. [QOJ14025] Bot bạn bè 2 (4)

Dùng thuật toán Prim để xây dựng cây khung nhỏ nhất. Độ phức tạp O(m log m).


#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main() {
    // Giải thuật chính
    return 0;
}

S. [QOJ5097] Tiểu P yêu thích học tập (4.5)

Áp dụng kỹ thuật chia để trị và biến đổi số học. Độ phức tạp O(n²√n).


#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main() {
    // Giải thuật chính
    return 0;
}

T. [QOJ14026] Du lịch 3 (3)

Dùng kỹ thuật xử lý khoảng cách với độ phức tạp O(n log n).


#include<bits/stdc++.h>
#define ll long long
using namespace std;

void solve() {
    // Giải thuật chính
}

int main() {
    // Xử lý đầu vào
    return 0;
}

U. [QOJ14022] Ethanol (9)

Giải phương trình vi phân bằng kỹ thuật số học. Độ phức tạp O(n³ log ε).


#include<bits/stdc++.h>
#define ld long double
using namespace std;

struct Polynomial {
    // Cài đặt đa thức
};

void solve() {
    // Giải thuật chính
}

int main() {
    // Xử lý đầu vào
    return 0;
}

V. [QOJ5018] nth (4.5)

Dùng kỹ thuật so sánh nhị phân với độ phức tạp O(n).


#include<bits/stdc++.h>
#include "nth.h"
using namespace std;

namespace Alice {
    // Giải thuật cho Alice
}

namespace Bob {
    // Giải thuật cho Bob
}

W. [QOJ5090] Bài toán thú vị (7.5)

Dùng kỹ thuật hình học và số phức để phân nhóm. Độ phức tạp O(n).


#include<bits/stdc++.h>
#include "tmp.h"
using namespace std;

void init(int N, bool, int) {
    // Khởi tạo
}

bool guess(unsigned long long A, int) {
    // Giải thuật chính
}

X. [QOJ37] Đường Thục (1.5)

Dùng ma trận để tính toán các giá trị liên quan đến cây. Độ phức tạp O(n log k).


#include<bits/stdc++.h>
#define ll long long
using namespace std;

struct Matrix {
    // Cài đặt ma trận
};

int main() {
    // Giải thuật chính
    return 0;
}

Y. [QOJ14023] Giải vô địch thế giới về câu cá (4)

Dùng kỹ thuật tổ hợp và biến đổi đa thức. Độ phức tạp O(n log n).


#include<bits/stdc++.h>
using namespace std;

namespace Polynomial {
    // Cài đặt đa thức
}

int main() {
    // Giải thuật chính
    return 0;
}

Z. [QOJ5017] Chuỗi cây bằng nhau (4.5)

Dùng kỹ thuật chia điểm trung tâm và xử lý đường kính. Độ phức tạp O(n log n).


#include<bits/stdc++.h>
#include<ext/pb_ds/hash_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#define ll long long
using namespace std;

struct Diameter {
    // Cài đặt đường kính
};

int main() {
    // Giải thuật chính
    return 0;
}

Thẻ: algorithm competitive-programming Combinatorics dynamic-programming graph-theory

Đăng vào ngày 11 tháng 6 lúc 05:00