1. 程式人生 > >線段樹詳解

線段樹詳解

延遲 操作 void space i++ 排序 string ++ 處理

#include"stdio.h"
#include"cstdio"
#include"algorithm"
#include"string.h"
using namespace std;
/**********************************************************************/
//線段樹版子
const int max_n=_____;
int B[max_n],A[max_n<<2];
void init(int l,int r,int rt)
{
if(l==r)
{
A[rt]=B[l];
return ;
}
int mid=(l+r)>>1;
init(l,mid,(rt<<1));
init(mid+1,r,(rt<<1)|1);
A[rt]=A[rt<<1]+A[(rt<<1)|1];
//或A[rt]=max(A[rt<<1]+A[(rt<<1)|1])等等具體看題意
}
//傳六值或五值具體看題意:
//如果是區段更新傳6個(配上下面延遲更新函數);點更新傳5個;
//1.區段:
void down(int rt,int len)
{
lazy[rt<<1]+=lazy[rt];
lazy[(rt<<1)|1]+=lazy[rt];
A[rt<<1]+=(len-len/2)*lazy[rt];
A[rt<<1]+=(len/2)*lazy[rt];
lazy[rt]=0;
//或其他操作,具體看題意
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
lazy[rt]+=val;
A[rt]+=val;
//或A[rt]=val等等,具體看題意
return ;
}
if(lazy[rt])
down(rt,r-l+1);
int mid=(l+r)>>1;
if(L<=mid)
update(L,R,val,l,mid,rt<<1);
if(R>mid)
update(L,R,val,mid+1,r,(rt<<1)|1);
A[rt]=A[rt<<1]+A[(rt<<1)|1];
//或A[rt]=max(A[rt<<1],A[(rt<<1)|1]);等其他處理
}
int query(int L,int R,int l,int r,int rt)
{
if(l>=L&&R>=r)
{
return A[rt];
}
if(laazy[rt])
down(rt,r-l+1);
int mid=(l+r)>>1;
int ans=0;
if(mid>=L)
ans+=query(L,R,l,mid,rt<<1);
if(R>mid)
ans+=query(L,R,mid+1,r,(rt<<1)|1);
return ans;
}
//2.點更新:
void update(int p,int val.int l,int r,int rt)
{
if(l==r)
{
A[rt]+=val;//或A[rt]=val等等,具體看題意
return ;
}
int mid=(l+r)>>1;
if(p<=mid)
update(p,val,l,mid,rt);
if(p>mid)
update(p,val,mid+1,r,rt);
A[rt]=A[rt<<1]+A[(rt<<1)|1];
//或A[rt]=max(A[rt<<1],A[(rt<<1)|1]);等其他處理
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
return A[rt];
int ans=0,mid=(l+r)>>1;
if(mid>=L)
ans+=query(L,R,l,mid,rt<<1);
if(R>mid)
ans+=query(L,R,mid+1,r,(rt<<1)|1);
return ans;
}
/*********************************************************************/
/*********************************************************************/
//與線段樹配套的數據離散化:
int len=0;
const int max_n=_____:
int B[max_n],C[max_n];//將C(C已排序)離散得B
void change(int n)
{
int i=0;
len=0;
B[++len]=C[++i];
for(;i<=n;i++)
{
if(C[i]-C[i-1]>1) B[++len]=C[i-1]+1;
if(C[i]!=B[len]) B[++len]=C[i];
}
}
//與其配套的二分:
int EF(int l,int r,ll num)
{
int mid=(l+r)>>1;
while(l<=r)
{
if(B[mid]>num) r=mid-1;
else if(B[mid]<num) l=mid+1;
else if(B[mid]==num) return mid;
mid=(l+r)>>1;
}
return mid;
}
/*********************************************************************/

線段樹詳解