求區間和;
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 目前常見的模板中,大體有兩種形式 使用簡單陣列,在函式引數表表示...