セグメントツリーテンプレートの要約(✩˙Ⱉ˙ฅ)
3719 ワード
うん、下書き箱の中の3編のかわいそうなのを見て...この1編をグーしないでほしい....(`・ω・´)
一.ツリーを作成単点修正+クエリー合計のツリー
2.単点修正+クエリー区間最大中のツリーはpush_を変更するだけback関数の内容、残りは変わらない
3.区間クエリのツリーを作成するにはlazy配列の初期化を追加するだけです
二.変更(増減)単点修正
2.区間修正
三.置換単点置換
2.区間置換
四.検索単点置換/修正の合計クエリー
2.区間置換の合計クエリー
3.区間修正の合計クエリー
まだ書き終わっていないので、後で帰ってきます(グーグーと言わないようにorzを先に送ります)
一.ツリーを作成
void push_up(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void build(int rt,int l,int r)//
{
if(l == r)
{
sum[rt] = a[l];
return;
}
int m = (l+r)>>1;
build(rt << 1,l,m);//
build(rt <<1|1,m+1,r);//
push_up(rt);
}
2.単点修正+クエリー区間最大中のツリーはpush_を変更するだけback関数の内容、残りは変わらない
void push_up(int rt)
{
sum[rt] = max(sum[rt<<1], sum[rt<<1|1]);//
}
3.区間クエリのツリーを作成するにはlazy配列の初期化を追加するだけです
void build(int rt,int l,int r)//
{
lazy[rt] = 0;
if(l == r)
{
sum[rt] = a[l];
return;
}
int m = (l+r)>>1;
build(rt << 1,l,m);//
build(rt <<1|1,m+1,r);//
push_up(rt);
}
二.変更(増減)
void update(int rt,int l,int r,int p,int v,bool judge)//
{
if(l == r)
{
if(judge)
sum[rt] += v;
else
sum[rt] -= v;
return;
}
int m = (l+r) >> 1;
if(p <= m)
update(rt << 1,l,m,p,v,judge);
else
update(rt << 1|1,m+1,r,p,v,judge);
push_up(rt);
}
2.区間修正
void push_down(int rt,int l,int r)
{
if(lazy[rt])
{
int m = (l+r) >> 1;
lazy[rt << 1] += lazy[rt];
lazy[rt << 1|1] += lazy[rt];
sum[rt << 1] += lazy[rt]*(m-l+1);
sum[rt << 1|1] += lazy[rt]*(r-m);
lazy[rt] = 0;
}
}
void update(int rt,int l,int r,int ll,int rr,int v)//
{
if(ll <= l&&r <= rr)
{
lazy[rt] += v;
sum[rt] += v*(r-l+1);
return;
}
push_down(rt,l,r);
int m = (l+r) >> 1;
if(ll <= m)
{
update(rt << 1,l,m,ll,rr,v);
}
if(rr > m)
{
update(rt << 1|1,m+1,r,ll,rr,v);
}
push_up(rt);
}
三.置換
void update(int rt,int l,int r,int p,int v)//
{
if(l == r)
{
sum[rt] = v;
return;
}
int m = (l+r) >> 1;
if(p <= m)
update(rt << 1,l,m,p,v);
else
update(rt << 1|1,m+1,r,p,v);
push_up(rt);
}
2.区間置換
void push_down(int rt,int l,int r)
{
if(lazy[rt])
{
int m = (l+r) >> 1;
lazy[rt << 1] = lazy[rt];
lazy[rt << 1|1] = lazy[rt];
sum[rt << 1] = lazy[rt]*(m-l+1);
sum[rt << 1|1] = lazy[rt]*(r-m);
lazy[rt] = 0;
}
}
void update(int rt,int l,int r,int ll,int rr,int v)//
{
if(ll <= l&&r <= rr)
{
lazy[rt] = v;
sum[rt] = v*(r-l+1);
return;
}
push_down(rt,l,r);
int m = (l+r) >> 1;
if(ll <= m)
{
update(rt << 1,l,m,ll,rr,v);
}
if(rr > m)
{
update(rt << 1|1,m+1,r,ll,rr,v);
}
push_up(rt);
}
四.検索
int query(int rt,int l,int r,int ll,int rr)
{
if(ll <= l && r <= rr)
return sum[rt];
int res = 0;
int m = (l+r) >> 1;
if(ll <= m)
res += query(rt << 1,l,m,ll,rr);
if(rr > m)
res += query(rt << 1|1,m+1,r,ll,rr);
return res;//
}
2.区間置換の合計クエリー
int query(int rt,int l,int r,int ll,int rr)
{
if(l == r)
return sum[rt];
push_down(rt,l,r);
int res = 0;
int m = (l+r) >> 1;
if(ll <= m)
res += query(rt << 1,l,m,ll,rr);
if(rr > m)
res += query(rt << 1|1,m+1,r,ll,rr);
push_up(rt);
return res;
}
3.区間修正の合計クエリー
int query(int rt,int l,int r,int ll,int rr)
{
if(l == r)
return sum[rt];
push_down(rt,l,r);
long long res = 0;
int m = (l+r) >> 1;
if(ll <= m)
res += query(rt << 1,l,m,ll,rr);
if(rr > m)
res += query(rt << 1|1,m+1,r,ll,rr);
return res;//
}
まだ書き終わっていないので、後で帰ってきます(グーグーと言わないようにorzを先に送ります)