區間資料結構

(前綴、差分、線段樹、BIT、Sparse Table)

前綴

給一個序列 AA 長度為 NN

QQ 筆詢問,求 i=lrAi\sum\limits_{i = l}^r{A_i}

 

Naive 作法:

一個迴圈搞定 ?
複雜度 O(QN)O(QN)

N105,Q105N \leq 10^5, Q \leq 10^5

定義 Bi:=j=1iAjB_i := \sum\limits_{j=1}^{i}A_j

 

i=lrAi=BrBl1\sum\limits_{i=l}^{r}A_i = B_r - B_{l-1}

時間複雜度 :

  1. 預處理 : O(N)O(N)
  2. 查詢     : O(1)O(1)

Atcoder Regular Contest 93 C

差分

給定序列 AA

定義序列 Bi:=AiAi1B_i := A_i - A_{i-1}

AA 的差分序列

數線上有NN個線段

ii 個線段為 [Li,Ri][L_i, R_i]

並且有QQ組詢問 XiX_i

回答在座標 XiX_i 上面是否有線段經過

N,Q,Li,Ri,Xi105N, Q, L_i, R_i, X_i \leq 10^5

 

想辦法算出 Ci:=座標 i 上的線段個數C_i := 座標  i  上的線段個數

對於所有線段 只要

CLiC_{L_i} 加一,

CRi+1C_{R_i+1} 減一

最後做一次前綴

nn個線段 起點終點分別為Li,RiL_i, R_i

並且有mm組詢問

qli,qriql_i, qr_i

回答是否存在線段 Lj,RjL_j, R_j使得

Ljqli,qriRjL_j \leq ql_i , qr_i \leq R_j

n,m,Li,Ri,qli,qri105n, m, L_i, R_i, ql_i, qr_i \leq 10^5

 

定義 righti:=Lji,max(Rj)right_i := \forall L_j \leq i, max(R_j)

可透過前綴 max 來取得

Codeforces 1358F

給正整數序列 A,BA, B 長度皆為 NN

你可以做很多次操作

  1. AA 做一次前綴和
  2. AA reverse

你想要把 AA 變成 BB
如果有解,請輸出一組可行解

N105N \leq 10^5

Ai,Bi1018 A_i, B_i \leq 10^{18}

sparse table

TIOJ 1603

給一個陣列 AA
QQ 筆詢問

(LijRi,max(Aj))(\forall L_i \leq j \leq R_i, max(A_j)) -

(LijRi,min(Aj))(\forall L_i \leq j \leq R_i, min(A_j))

定義dpi,j:=ik<i+2j,max(ak)dp_{i,j}:= \forall i \leq k < i + 2^j, max(a_k)

我們可得到下列關係式

dpi,j=max(dpi,j1,dpi+2j1,j1)dp_{i,j} = max(dp_{i, j-1}, dp_{i+2^{j-1}, j-1})

dpi,0=aidp_{i, 0} = a_i

詢問 [L,R)[L, R)

k=log2(RL)k = \lfloor log_2 (R-L)\rfloor

max(dpL,k,dpR2k,k)max(dp_{L, k}, dp_{R-2^k, k})

線段樹

Title Text

關於線段樹節點

假如一個節點 代表了區間 [L,R][L, R] 的資訊

而且有左右子樹 [L,M],[M+1,R][L, M], [M+1, R]

當我想要算出max[L,R] max[L, R]

我只要求 max(leftchild,rightchild)max(leftchild, rightchild) 就好了

 

以指標來記錄左右子樹

struct segment_tree{
    struct node{
        int val;
        node* left = NULL, * right = NULL;
        node(int v):val(v){}
        void update() { val = max(left->val, right->val); }
        node(node* a, node* b){
            val = max(a->val, b->val);
            left = a, right = b;
        }
    };
    node* root;
    node* init(int l, int r, int* v){
        if(l == r)return new node(v[l]);
        int m = l + r >> 1;
        return new node(init(l, m, v), init(m+1, r, v));
    }
    void modify(int pos, int nv, node* now, int l = 1, int r = n){
        if(l == r) return now->val = nv, void();
        if(pos > r || pos < l)return;
        int m = l + r >> 1;
        modify(pos, nv, now->left, l, m);
        modify(pos, nv, now->right, m+1, r);
        now->update();
    }
    int query(int ql, int qr, node* now, int l = 1, int r = n){
        if(ql > r || qr < l) return -(1 << 29);
        if(ql <= l && r <= qr) return now->val;
        int m = l + r >> 1;
        return max(query(ql, qr, now->left, l, m),
                query(ql, qr, now->right, m+1, r));
    }
};

陣列形線段樹

以 1 作為根

對於節點 iii2,i2+1i*2, i*2+1 分別作為左右子樹

const int maxn = 1 << 20;
const int inf = 1 << 29;
struct segment_tree{
    int max_val[maxn << 1];
    void modify(int pos, int new_val, int l = 1, int r = n, int i = 1){
        if (l > pos || r < pos) return;
        if (l == r) return max_val[i] = new_val, void();
        int m = l + r >> 1;
        modify(pos, new_val, l, m, i<<1);
        modify(pos, new_val, m+1, r, i<<1|1);
        max_val[i] = max(max_val[i<<1], max_val[i<<1|1]);
    }
    int query_max(int ql, int qr, int l = 1, int r = n, int i = 1) {
        if (ql > r || qr < l) return -inf;
        if (ql <= l && qr >= r) return max_val[i];
        int m = l + r >> 1;
        return max(query_max(ql, qr, l, m, i<<1),
        		query_max(ql, qr, m+1, r, i<<1|1);
    }
};

Binary Indexed Tree

(Fenwick Tree)

定義 Vi:=ilowbit(i)+1iaiV_i := \sum\limits_{i - lowbit(i)+1}^{i} a_i

lowbit(i):=2least significant bit(i)lowbit(i) := 2^{least  significant  bit(i)}

 

x :              011010100

lowbit(x) : 000000100

Code

struct bit {
    int v[maxn];
    void add(int i, int val) {
        for (;i <= n;i += i&-i)
            v[i] += val;
    }
    int query(int i) {
        int res = 0;
        for (;i;i ^= i&-i)
            res += v[i];
        return res;
    }
}tree;

codeforces 1191F

Made with Slides.com