線段樹 小整理

2021-08-22 02:27:57 字數 4148 閱讀 9881

求區間和;

ll sum[maxn<<2];//儲存區間和

ll add[maxn<<2];//懶惰標記

ll a[maxn];//用於輸入儲存資料

求區間和的函式:

void pushup(int x)

建立線段樹:

void buildtree(int l,int r,int rt)

int m=(l+r)>>1;

buildtree(l,m,rt<<1);//建立左子樹

buildtree(m+1,r,rt<<1|1);//右子樹

pushup(rt);//維護各區間的加和

}

單點修改:

void singlemodify(int x,int l,int l,int r,int rt)

int m=(l+r)>>1;

if(m>l)

else singlemodify(x,l,m+1,r,rt<<1|1);//查詢右邊

pushup(rt);//更新區間

}

區間修改:

void qmodify(int x,int l,int r,int l,int r,int rt)

int m=(l+r)>>1;

pushdown(r-m,m-l+1,rt);

if(m>=l) qmodify(x,l,r,l,m,rt<<1);

if(r>m) qmodify(x,l,r,m+1,r,rt<<1|1);

pushup(rt);

}

延時標記函式

void pushdown(int rn,int ln,int rt)

return ;

}

查詢:

ll query(int l,int r,int l,int r,int rt)

int m=(l+r)>>1;

pushdown(r-m,m-l+1,rt);//注意標記下推,因為可能會查詢到未修改的節點

ll ans=0;

if(m>=l) ans+=query(l,r,l,m,rt<<1);

if(m線段樹區間合併類的做法

例題hdu1540

#include using namespace std;

int n,m;

#define maxx 50010

struct node

sum[maxx<<2];

void pushup(int rt)

if(sum[rt<<1|1].rs==sum[rt<<1|1].r-sum[rt<<1|1].l+1)

}void buildtree(int l,int r,int rt)

}void update(int rt,int num,int x)

else

return ;

}int mid=(sum[rt].l+sum[rt].r)>>1;

if(num<=mid)

else

pushup(rt);

}int query(int rt,int num)

int mid=(sum[rt].r+sum[rt].l)>>1;

if(num<=mid)

else

}else

else return query(rt<<1|1,num);

}}int main()

else if(op=='r')

else if(op=='q')}}

//system("pause");

return 0;

}

poj3667

//#include #include #include #include #include #include #include #include using namespace std;

int n,m;

#define maxx 50010

struct node

sum[maxx<<2];

void pushup(int rt)

if(sum[rt<<1|1].rs==sum[rt<<1|1].r-sum[rt<<1|1].l+1)

}void pushdown(int rt,int k)

}void buildtree(int l,int r,int rt)

}void update(int rt,int l,int r,int va)

pushdown(rt,sum[rt].r-sum[rt].l+1);

int mid=(sum[rt].l+sum[rt].r)>>1;

if(mid>=l) update(rt<<1,l,r,va);

if(mid>1;

if(sum[rt<<1].ms>=num)

else if(sum[rt<<1].rs+sum[rt<<1|1].ls>=num)

else return query(rt<<1|1,num);

}int main()

sum[maxn<<2];

void pushup(int rt)

void buildtree(int rt,int l,int r)

}void update(int rt,int num,int value)

int mid=(sum[rt].l+sum[rt].r)>>1;

if(num<=mid)

else update(rt<<1|1,num,value);

pushup(rt);

}int querymax(int rt,int l,int r)

if(sum[rt].l==sum[rt].r) return sum[rt].maxv;

int mid=(sum[rt].l+sum[rt].r)>>1;

int maxans=0;

if(mid>=l)

if(mid=l&&sum[rt].r<=r)

if(sum[rt].l==sum[rt].r) return sum[rt].minv;

int mid=(sum[rt].r+sum[rt].l)>>1;

int minans=0x3f3f3f3f;

if(mid>=l)

if(mid按樹的時間戳建立線段樹

題 hdu3974(有區間修改,懶惰標記)

#include using namespace std;

#define maxn 50010

typedef long long ll;

struct node

sum[maxn<<2];

int l[maxn],r[maxn];

vectorb[maxn];

int n,m;

int fa[maxn];

int cnt;

void dfs(int u)//通過深搜的時間戳確定每個點的管轄範圍

r[u]=cnt;

}void pushdown(int rt)

}void buildtree(int rt,int l,int r)

else

}void update(int rt,ll t,int l,int r)

pushdown(rt);

int mid=(sum[rt].l+sum[rt].r)>>1;

if(mid>=l)

if(mid>1;

if(mid>=s)

else return query(rt<<1|1,s);

}int main()

for(int i=1;icnt=0;

for(int i=1;i<=n;i++)

}buildtree(1,1,n);

scanf("%d",&m);

printf("case #%d:\n",e);

char op;

int x;

ll y;

for(int i=1;i<=m;i++)

else }}

//system("pause");

return 0;

}

線段樹再整理

和思路來自 傳送門 建樹模板 一 線段樹基本概念 1 概述 線段樹,類似區間樹,是乙個完全二叉樹,它在各個節點儲存一條線段 陣列中的一段子陣列 主要用於高效解決連續區間的動態查詢問題,由於二叉結構的特性,它基本能保持每個操作的複雜度為o lgn 性質 父親的區間是 a,b c a b 2 左兒子的區...

線段樹入門整理

線段樹 interval tree 是把區間逐次二分得到的一樹狀結構,它反映了包括歸併排序在內的很多分治演算法的問題求解方式。宣告 1 include2 include3 const int maxnode 2097152 4 const int max 1000003 5 struct noden...

線段樹入門 資料整理

c題題解,專題訓練一 講解線段樹從入門到高階 線段樹開闢的空間一般是需要儲存的資料的4倍。線段樹使用了二分的思想 我自己認為 把區域進行不斷的二分。她能把一些對於區間 或者線段 的修改 維護,從 o n 的時間複雜度變成 o logn 目前常見的模板中,大體有兩種形式 使用簡單陣列,在函式引數表表示...