用二維線段樹優化你的查詢演算法

一、什麼是二維線段樹

線段樹是一種數據結構,它可以對一維的區間進行查詢和修改操作。一維線段樹本質上就是一棵二叉樹,每個節點代表一個區間。而二維線段樹則通過拆分成若干個一維線段樹解決二維區間的查詢問題。

在二維平面上建立一棵平衡二叉樹,節點數為 $O(n\log n)$,並且使每個節點代表的區域是相等的。每個節點存儲這個區域的信息。每個節點代表一個矩形,在其兒子節點中將該矩形分成四個區域。具體實現時,只需要在每個節點記錄它的兒子節點的編號即可。


const int MAXN = 1e3;

struct node {
    int data;
    int l, r, d, u; // 左邊界,右邊界,下邊界,上邊界
    int son[4];
} tree[MAXN*MAXN];
int root = 1, tot = 1;

// 區間查詢
int query(int p, int l, int r, int d, int u) {
    if(p == 0) return 0;
    if(l <= tree[p].l && tree[p].r <= r && d <= tree[p].d && tree[p].u <= u) return tree[p].data;
    int res = 0;
    int midx = (tree[p].l+tree[p].r)/2, midy = (tree[p].d+tree[p].u)/2;
    if(l <= midx && d  midx && d <= midy) res += query(tree[p].son[1], l, r, d, u);
    if(l  midy) res += query(tree[p].son[2], l, r, d, u);
    if(r > midx && u > midy) res += query(tree[p].son[3], l, r, d, u);
    return res;
}

二、二維線段樹在常見問題中的應用

二維線段樹的常見用途有區間查詢和矩陣求和。在一個 $N\times M$ 的矩陣中,選擇若干個位置的數,並將它們全部加起來,問題可以轉化為查詢某些行和列的區間和。使用二維線段樹可以將時間複雜度從 $O(NM)$ 優化到 $O((N+Q)\log^2N)$,其中 $Q$ 為查詢次數。

三、使用二維線段樹進行優化

在二維線段樹中,每個節點代表一塊區間,節點內存儲了這一塊區間內的數據。對於第一維的數據,我們可以直接將其放在第一維的線段樹上。而對於第二維的數據,我們可以開一個另外的數組來存儲。在查詢、修改時,二者都會同時被更新。

比如在一個二維平面上,給定點 $(x_1,y_1)$ 和 $(x_2,y_2)$,查詢這兩個點構成的矩形中所有點的權值和。我們可以維護兩棵線段樹,分別對第一維和第二維進行建樹。查詢操作時,時間複雜度為 $O(\log^2n)$。


const int MAXN = 1e3;

struct node {
    int data;
    int l, r, son[2];
} tr[MAXN*4][MAXN*4];
int n;

void buildy(int x, int p, int l, int r) {
    if(l == r) {
        // 對於每個葉子節點,開一個數組儲存值
        for(int i = 1; i <= n; i++) {
            tr[x][p].data += val[i][l];
        }
        return;
    }
    int m = (l+r)/2;
    tr[x][p].l = l, tr[x][p].r = r;
    buildy(x, p*2, l, m);
    buildy(x, p*2+1, m+1, r);
    tr[x][p].data = tr[x][p*2].data+tr[x][p*2+1].data;
}

void buildx(int p, int l, int r) {
    if(l == r) {
        buildy(p, 1, 1, n);
        return;
    }
    int m = (l+r)/2;
    tr[p][0].l = l, tr[p][0].r = r;
    buildx(p*2, l, m);
    buildx(p*2+1, m+1, r);
    for(int i = 1; i <= 4*n; i++) {
        tr[p][i].r = tr[p][0].r;
        tr[p][i].l = tr[p][0].l;
    }
    for(int i = 0; i < n; i++) {
        for(int j = 1; j data+tr[p][i*4+j].son[1]->data;
        }
    }
}

int queryy(int x, int p, int l, int r, int d, int u) {
    if(d <= tr[x][p].l && tr[x][p].r <= u) {
        return tr[x][p].data;
    }
    int m = (tr[x][p].l+tr[x][p].r)/2, res = 0;
    if(d  m) res += queryy(x, p*2+1, l, r, d, u);
    return res;
}

int queryx(int p, int l, int r, int d, int u, int dl, int ur) {
    if(dl <= l && r <= ur) {
        return queryy(p, 1, dl, ur, d, u);
    }
    int m = (l+r)/2, res = 0;
    if(dl  m) res += queryx(p*2+1, m+1, r, d, u, dl, ur);
    return res;
}

四、小結

二維線段樹的常見應用有區間查詢和矩陣求和。它將單維線段樹的思想擴展至二維,拆分成多個一維線段樹,從而可以優化查詢的時間複雜度,減少不必要的計算。在實際應用中,可以將第一維和第二維分別使用不同的數據結構,來達到更好的效果。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/312771.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2025-01-06 15:17
下一篇 2025-01-06 15:17

相關推薦

  • Python官網中文版:解決你的編程問題

    Python是一種高級編程語言,它可以用於Web開發、科學計算、人工智慧等領域。Python官網中文版提供了全面的資源和教程,可以幫助你入門學習和進一步提高編程技能。 一、Pyth…

    編程 2025-04-29
  • 蝴蝶優化演算法Python版

    蝴蝶優化演算法是一種基於仿生學的優化演算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化演算法Python版…

    編程 2025-04-29
  • Python實現爬樓梯演算法

    本文介紹使用Python實現爬樓梯演算法,該演算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • AES加密解密演算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密演算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES演算法,並對實現過程進…

    編程 2025-04-29
  • 掌握magic-api item.import,為你的項目注入靈魂

    你是否曾經想要導入一個模塊,但卻不知道如何實現?又或者,你是否在使用magic-api時遇到了無法導入的問題?那麼,你來到了正確的地方。在本文中,我們將詳細闡述magic-api的…

    編程 2025-04-29
  • Harris角點檢測演算法原理與實現

    本文將從多個方面對Harris角點檢測演算法進行詳細的闡述,包括演算法原理、實現步驟、代碼實現等。 一、Harris角點檢測演算法原理 Harris角點檢測演算法是一種經典的計算機視覺演算法…

    編程 2025-04-29
  • 數據結構與演算法基礎青島大學PPT解析

    本文將從多個方面對數據結構與演算法基礎青島大學PPT進行詳細的闡述,包括數據類型、集合類型、排序演算法、字元串匹配和動態規劃等內容。通過對這些內容的解析,讀者可以更好地了解數據結構與算…

    編程 2025-04-29
  • 瘦臉演算法 Python 原理與實現

    本文將從多個方面詳細闡述瘦臉演算法 Python 實現的原理和方法,包括該演算法的意義、流程、代碼實現、優化等內容。 一、演算法意義 隨著科技的發展,瘦臉演算法已經成為了人們修圖中不可缺少…

    編程 2025-04-29
  • 神經網路BP演算法原理

    本文將從多個方面對神經網路BP演算法原理進行詳細闡述,並給出完整的代碼示例。 一、BP演算法簡介 BP演算法是一種常用的神經網路訓練演算法,其全稱為反向傳播演算法。BP演算法的基本思想是通過正…

    編程 2025-04-29
  • 粒子群演算法Python的介紹和實現

    本文將介紹粒子群演算法的原理和Python實現方法,將從以下幾個方面進行詳細闡述。 一、粒子群演算法的原理 粒子群演算法(Particle Swarm Optimization, PSO…

    編程 2025-04-29

發表回復

登錄後才能評論