1. 程式人生 > >字典樹基礎

字典樹基礎

左右 using names code void 子節點 namespace name 查詢

字典樹:字典樹用來儲存區域信息

主要有五種操作:

建樹、單點查詢、單點修改、區間查詢、區間修改。

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

struct node
{
       int l,r,w;//l,r分別表示區間左右端點,w表示區間和
}tree[4*n+1];//字典樹要開四倍空間

void build(int l,int r,int k)
{
    tree[k].l=l;tree[k].r=r;
    if(l==r)//葉子節點 
    {
        scanf("%d",&tree[k].w);
        
return ; } int m=(l+r)/2; build(l,m,k*2);//左孩子 build(m+1,r,k*2+1);//右孩子 tree[k].w=tree[k*2].w+tree[k*2+1].w;//狀態合並,此結點的w=兩個孩子的w之和 } int ask(int k,int pos) { if(tree[k].l==tree[k].r) //當前結點的左右端點相等,是葉子節點,是最終答案 { return tree[k].w; } int m=(tree[k].l+tree[k].r)/2
; if(pos<=m) ask(k*2);//目標位置比中點靠左,就遞歸左孩子 else ask(k*2+1);//反之,遞歸右孩子 } void add(int k,int pos,int v) { if(tree[k].l==tree[k].r)//找到目標位置 { tree[k].w+=v; return; } int m=(tree[k].l+tree[k].r)/2; if(pos<=m) add(k*2); else add(k*2+1); tree[k].w=tree[k*2
].w+tree[k*2+1].w;//所有包含結點k的結點狀態更新 } void sum(int k,int left,int right) { if(tree[k].l>=left && tree[k].r<=right) { ans+=tree[k].w; return; } int m=(tree[k].l+tree[k].r)/2; if(left<=m) sum(k*2); if(right>m) sum(k*2+1); }

字典樹基礎