- VisualStudio2022
- pprof-Hướng dẫn sử dụng nó trong bản mạng trực tiếp
- Triển khai C# các loại hộp chọn nhiều màu lựa chọn thả xuống, cây lựa chọn nhiều màu lựa chọn thả xuống và các nút tối đa
- [Ghi chú học tập] Cơ sở dữ liệu cấu trúc: cat tree
Phân đoạn cây là một cây dữ liệu cấu trúc rất hiệu quả được sử dụng để giải quyết các vấn đề về truy vấn và sửa đổi khoảng thời gian. quy tắc và cách thực hiện đoạn đường cây cũng như khám phá các ứng dụng kịch bản của nó.
Trong một số cổ điển toán học, ý tưởng như cho một mảng, các phép toán sau thường được yêu cầu:
Đối với các truy vấn khoảng trống, chúng tôi có thể duyệt trực tiếp các khoảng trống để tính toán kết quả mỗi lần; thay đổi khoảng trống, chúng tôi có thể duyệt toàn bộ khoảng phụ để cập nhật. array length. Độ phức tạp về thời gian của phương pháp này là \(O(n)\). mảng lớn thì hiệu quả sẽ trở lại nên không thể được chấp nhận.
Cây đoạn thẳng ra đời.
Phân đoạn cây là phân tích cây nhị phân được sử dụng để lưu trữ và xử lý khoảng thời gian thông tin một cách hiệu quả.
Đoạn phân đoạn liên tục chia không có các mảng chỉ số thành nhiều khoảng và sử dụng phân tích cây nhị phân để lưu trữ thông tin của các khoảng này:
Ví dụ, cho mảng [1, 3, 5, 7, 9, 11], đoạn thẳng của nó như sau:
[0, 5] / \ [0, 2] [3, 5] / \ / \ [0, 1] (2, 2) [3, 4] (5, 5) / \ / \ (0, 0) (1, 1) (3, 3)(4, 4)
Trong câu Hỏi điều này, chúng tôi lưu trữ tổng số các khoảng.
Bảng thông tin chỉ sử dụng 1 lần không gian và không yêu cầu dư thừa dữ liệu, khi phân tích đoạn cây nhị phân thường được biểu hiện bằng mảng. \(4n\) vì:
Tất nhiên, phức tạp của không gian là \(O(n)\) và chỉ có hệ số thay đổi. số trong ví dụ trên.
Sau đây là ví dụ mã hóa để xây dựng phân đoạn cây:
#bao gồm #bao gồm use vector cây không có tên std;; // Phân tích cây bối rối lười; > sẽ được sử dụng sau arr ; // Dữ liệu gốc được sử dụng để xây dựng cây void build(int node, int start, int end) { if (start == end) { // Cây nút lá[node] = arr[start] ; } khác { // Các nút không có lá tiếp tục được chia thành hai phần int mid = (start + end) / 2; nút 2 * + 1; nút int right_child = 2 * nút + 2; build(right_child, mid + 1, end); tree[node] = tree[left_child] + tree[right_child] // Tổng khoảng là tổng của bên trái và bên phải} }
Hỗ trợ đoạn đường hỗ trợ các kết quả khoảng trống truy vấn và chia bài toán thành các khoảng nhỏ để xử lý thông tin qua phương pháp chia for value. trong đoạn thẳng sau đây là mã thực thi:
int query(int node, int start, int end, int l, int r) { if (r < start || l > end) { return 0; // hoàn toàn tách rời} if (l <= start && end < = r ) { return tree[node]; // Bao gồm hoàn toàn} // If bao gồm một int mid = (bắt đầu + kết thúc) / 2; int left_sum = query(left_child, start, mid, l, r) ; truy vấn(right_child, mid + 1, end, l, r return left_sum + right_sum;
Nếu muốn sửa đổi khoảng \([1,4]\), chúng tôi có thể thấy rằng khoảng thời gian cuối cùng được chia thành nhiều khoảng phụ và Không phải lúc nào cũng đi xuống đáy, điều này giúp cải thiện đáng kể hiệu quả.
[0, 5][36]× / \ [0, 2][9]× [3, 5][27]× / \ / \ [0, 1][4]× (2, 2)[5] √ [3, 4][16]√ (5, 5)[11] / \ / \ (0, 0)[1] (1, 1)[3]√ (3, 3)[7] (4, 4)[9]
Những thay đổi ở đây nút bên dưới sẽ ảnh hưởng đến giá trị của nút cha và tổng sẽ được tính lại sau khi quá trình xử lý kết thúc end.
void update(int node, int start, int end, int idx, int val) { if (start == end) { tree[node] = val } else { int mid = (start + end) / 2; nút + 1; int right_child = 2 * nút + 2; if (idx <= mid) { update(left_child, start, mid, idx, val } else { update(right_child, mid + 1, end, idx, val); } cây[nút] = cây[left_child] + cây[right_child];
Vẫn sử dụng ví dụ vừa rồi, giả sử rằng giá trị của số dưới 1 đã được sửa đổi:
[0, 5][37]× / \ [0, 2][10]× [3, 5][27] / \ / \ [0, 1][5]× (2, 2)[5] [ 3, 4][16] (5, 5)[11] / \ / \ (0, 0)[1] (1, 1)[4]√ (3, 3)[7] (4, 4)[9]
Đây là phần khó nhất của đoạn cây. chuyển tiếp lười biếng. Update khi cần thiết.
Cụ thể, nếu chúng tôi muốn sửa đổi giá trị của một khoảng nhất định (ví dụ: tăng \(a\)), chúng tôi vẫn sẽ chia nó Thay vào đó, tôi chỉ sửa đổi nút này và đặt dấu lười ở nút đó thành \(a\), biết rằng tất cả các nút của tôi phải được bổ sung bằng \(a\), nhưng thực tế tôi vẫn chưa làm được điều đó. chúng tôi sẽ xóa dấu gạch ngang và đưa nó xuống một cấp.
void updateRange(int node, int start, int end, int l, int r, int val) { if (lazy[node] != 0) { tồn tại không , đẩy nó xuống một lớp cây[node] += (end - start + 1) * lười biếng[nút]; bắt đầu != end) { lười [2 * nút + 1] += lười [ nút 2 * + 2] += lười[nút]; } lười [nút] = 0; if (r < bắt đầu || l > kết thúc) { // Hoàn toàn tách return } nếu (l <= bắt đầu && kết thúc <= r) { // Đã bao gồm đầy đủ, sau đó dừng lại ở đây và sử dụng cây đánh dấu lười đỉnh [node] += (end - start + 1) * val; if (start != end) { lười [2 * nút + 1] += val ; } return; } // If được bao gồm updateRange(2 * node + 2, mid + 1, end, l, r, val); cây[nút] = cây[2 * nút + 1] + cây[2 * nút + 2 ] }
Vẫn làm theo ví dụ trên, tăng \([1,4]\) lên 1, ta thấy nó được đánh dấu tại \([3,4]\) và không còn lan truyền xuống dưới nữa. Vì vậy, việc đánh dấu ngu ngốc là bắt buộc đối với phân đoạn cây chứ không phải là một lớp phủ trên bánh.
Mặc dù giá trị của cây con tạm thời không chính xác, nhưng việc truy cập vào cây chắc chắn sẽ vượt qua dấu vết lười biếng. Đưa nó xuống, đảm bảo rằng điều đó sẽ kéo dài. khoảng trống cũng cần thêm một đoạn dấu thăng lên và xuống (tức là phần if (lazy[node] != 0)).
[0, 5][40]× / \ [0, 2][11]× [3, 5][29]× / \ / \ [0, 1][5]× (2, 2)[6] √ [3, 4][18|+1]√ (5, 5)[11] / \ / \ (0, 0)[1] (1, 1)[4]√ (3, 3)[7] (4, 4)[9]
Chúng tôi nhận thấy rằng mỗi khi thực hiện một truy vấn hoặc sửa đổi, đường cây sẽ phân tách bằng khoảng cách cách chia đôi và cuối cùng phân tích khoảng trống thành các phân đoạn lớn khoảng log n, điều này giúp cải thiện đáng kể hiệu Ngay trong kết quả. trường hợp xấu nhất, tạo thành công phân tích cây phân tách left left and right of tree. thùng là \. (O(\log n)\).
Khi ý tưởng thuật toán hoàn toàn giống nhau, cây nhị phân cũng có thể được phát triển bằng cách sử dụng con trỏ và không trả lời use. thớt. Nhược điểm Phương pháp này sẽ không được hiển thị trong bài viết này.
Trong bản văn của bài viết này (duy trì mảng), các phiên bản của mảng mảng tĩnh hơn và được sử dụng phổ biến hơn. Nếu bạn muốn duy trì phạm vi giá trị lớn nhưng thưa thớt, phiên bản con trỏ có thể tiết kiệm rất nhiều dung lượng.
Ngoài ra, việc truy vấn và sửa đổi khoảng thời gian, phân đoạn đường cây vẫn có thể giải quyết các vấn đề sau:
Cây phân đoạn xử lý tốt các thuộc tính khoảng có thể phân tách (chẳng hạn như tổng hợp, cực đại, cực tiểu, tích, vv), nhưng đối với một số thuộc tính phi tuyến, việc xử lý này khó hoặc không có hiệu quả , một số toán về khoảng. không thể sử dụng đường phân đoạn cây. Chế độ này không thể được thực hiện bằng cách đơn giản kết hợp các kết quả của hai khoảng phụ vì nó yêu cầu tổng thông tin could. khoảng cách. Ý tưởng phân chia và chính phục của đoạn đường cây.
Cuối cùng, bài viết này về giải thích chi tiết về cây phân đoạn khoảng cổ điển: từ nguyên tắc đến thực hiện kết nối end ở đây. thực hiện, vui lòng tìm kiếm các bài viết của CFSDN hoặc. của tôi trong tương lai .
Bài viết này được chia sẻ từ Cộng đồng Huawei Cloud "Đào tạo phân tán LLM mô hình lớn", tác giả: Hua Shanghua_Lancer. Với sự tăng trưởng nhanh chóng về số lượng tham số mô hình ngôn ngữ và dữ liệu đào tạo cần thiết, nguồn lực hạn chế trên một máy không còn có thể đáp ứng yêu cầu đào tạo mô hình ngôn ngữ lớn. Cần thiết kế đào tạo phân tán
Bài viết này được chia sẻ từ Cộng đồng Huawei Cloud "Năm thuật toán cơ bản-Phương pháp lập trình động", tác giả: Daikin (đến từ Nội Mông). 1. Khái niệm cơ bản của quy hoạch động rất giống với phương pháp chia để trị. Điểm khác biệt là khi giải một bài toán con, lời giải của bài toán con đó sẽ được lưu lại và có thể sử dụng trực tiếp khi giải các bài toán con tiếp theo.
pip install scp pip install pexpect Mã kiểm tra: import os import stat import paramiko # Dùng để gọi lệnh scp def s
Tôi hiện đang triển khai dịch vụ REST "mã thông báo". Mã thông báo chỉ là một chuỗi được xây dựng từ một số tham số, sau đó được băm và hết hạn sau một khoảng thời gian nhất định. Tôi muốn có điểm cuối trong dịch vụ REST có thể xác minh mã thông báo,
Khi bật tính năng xóa mềm, tôi thêm bản ghi trên máy khách, Đẩy, xóa bản ghi đã thêm, sau đó thử thêm bản ghi mới (và sau đó Đẩy) bằng cùng khóa chính với bản ghi ban đầu, tôi nhận được một ngoại lệ. Thực thểDomainManager
Khi bật tính năng xóa mềm, tôi thêm bản ghi trên máy khách, Đẩy, xóa bản ghi đã thêm, sau đó thử thêm bản ghi mới (và sau đó Đẩy) bằng cùng khóa chính với bản ghi ban đầu, tôi nhận được một ngoại lệ. Thực thểDomainManager
Tôi có một ứng dụng nhận thông tin thời tiết cứ sau x giây. Tôi muốn lưu dữ liệu này vào tệp XML. Tôi có nên tạo tệp XML mới cho mỗi thông báo thời tiết hay nối thêm từng thông báo vào cùng một tệp XML không? Tôi không chắc chắn về tiêu chuẩn XML
Tôi đoán hầu hết chúng ta đều phải đối mặt với vấn đề này vào một lúc nào đó, vì vậy tôi nghĩ tôi sẽ hỏi. Khi bạn có nhiều bộ sưu tập trong BLL của mình và bạn thấy mình viết đi viết lại cùng một vị từ nội tuyến (ẩn danh) cũ, thì việc đóng gói rõ ràng là cần thiết, nhưng cách tốt nhất để đạt được điều đó là
Tôi có một số mã C# đã chạy được một thời gian.. Tôi phải nói rằng mặc dù tôi hiểu những điều cơ bản về nguyên tắc OO nhưng rõ ràng có nhiều cách để lột da một con mèo (mặc dù tôi ghét cụm từ đó!). Vì vậy, tôi có một lớp trừu tượng cơ bản là lớp dịch vụ dữ liệu cơ bản như sau
Tôi đang thiết kế một hệ thống cơ sở dữ liệu SQL (sử dụng Postgre) và tôi có một câu hỏi, cách phổ biến để tạo mối quan hệ/tham chiếu vẫn tồn tại ngay cả khi đối tượng được tham chiếu bị xóa. Ví dụ: có UserORM và Act
Mục tiêu của chúng tôi là tìm kiếm một chuỗi do người dùng nhập và đếm xem có bao nhiêu nguyên âm được tìm thấy trong đó. Thật không may, tôi bị kẹt ở đây, có ai giúp được không? def numVowels(s): nguyên âm= "AEIOUaeiou" if s
Tôi có chức năng xoay hoạt động trên mảng int "mục" của mình. Mã bên dưới thực hiện điều đó ngoại trừ việc tôi chuyển giá trị một cách không cần thiết. Tôi đang cố gắng thực hiện xoay vòng "tại chỗ". Ý tôi là ptrs sẽ được tăng hoặc giảm thay vì lấy giá trị từ mảng. Tôi cần cách này
Tôi có một json được lưu trữ trong thư mục tài liệu ứng dụng của mình và tôi cần sử dụng nó trong tất cả các Chế độ xem của mình. Tôi đang tải json và thêm nó vào NSMutableArray trong mỗi Chế độ xem. Nhưng bây giờ tôi hiểu rằng tôi có thể
Tôi đã bắt đầu một dự án bằng C++. Quản lý bộ nhớ bằng ngôn ngữ này là điều mới mẻ đối với tôi. Tôi đã từng tạo đối tượng bằng cách sử dụng new() rồi truyền con trỏ, và trong khi nó hoạt động, việc gỡ lỗi rất khó khăn và mọi người sẽ nhìn tôi buồn cười khi họ nhìn thấy mã. Tôi không có nó
Đã kết thúc. Câu hỏi này lạc đề. Hiện tại nó không chấp nhận câu trả lời. Bạn muốn cải thiện câu hỏi này? Cập nhật câu hỏi để nó có chủ đề Stack Overflow. Đóng cửa 10 năm trước. Cải thiện điều này
Giữ các lớp được liên kết lỏng lẻo là một khía cạnh quan trọng của việc viết mã dễ hiểu, sửa đổi và gỡ lỗi - tôi hiểu rồi. Tuy nhiên, là một người mới, tôi hầu như luôn vượt quá ví dụ đơn giản nhất mà tôi đang gặp khó khăn. Tôi ít nhiều hiểu cách đóng gói chuỗi, số nguyên và các kiểu dữ liệu đơn giản
Tôi thấy rằng tôi cần phải viết nhiều mã trùng lặp vì tôi không thể gọi các hàm từ Bộ điều khiển khác. Ví dụ: ở đây nội dung nguồn cấp tin tức được lặp lại trong mã của tôi, tôi thực hiện một số việc cụ thể cho Bộ điều khiển và sau đó cần tải nguồn cấp tin tức của mình như thế này
Giả sử bạn cần một kiểu dữ liệu số cho phép các giá trị trong một phạm vi xác định. Cụ thể hơn, giả sử bạn muốn xác định một loại số nguyên có giá trị tối thiểu là 0 và giá trị tối đa là 5000. Tình trạng này xảy ra trong nhiều tình huống, chẳng hạn như khi lập mô hình các kiểu dữ liệu cơ sở dữ liệu, kiểu dữ liệu XSD. hiện hữu
Giả sử tôi muốn lặp qua toàn bộ mảng để truy cập từng phần tử. Đây có phải là thông lệ tiêu chuẩn để các nhà phát triển JavaScript sử dụng vòng lặp for, vòng lặp for...in hoặc vòng lặp for...of không? Ví dụ: var myArray = ["app
Tôi có một ứng dụng SL4/ria cũ mà tôi muốn thay thế bằng Breeze. Tôi có câu hỏi về việc sử dụng bộ nhớ và bộ nhớ đệm. Ứng dụng của tôi tải danh sách công việc (một người dùng thông thường có quyền truy cập vào khoảng 1.000 công việc này). Ngoài ra còn có rất nhiều
Tôi là một lập trình viên xuất sắc, rất xuất sắc!