數列求和【線段樹基礎】
線段樹基礎題
操作包括:1.點修改 2.區間修改 3.區間查詢
// 線段樹基礎:數列求和
#include<stdio.h>
#define maxn 10007//數列總個數
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
int sum[maxn<<2],add[maxn<<2];//sum求和,add為惰性標記
int a[maxn],n;//存原資料下標從1開始
//PushUp 更新結點資訊,這裡是求和 。用左右子結點更新父親結點
void PushUp(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
//Build函式建樹
void Build(int l,int r,int rt)
{
if(l==r){
sum[rt]=a[l];
return;
}
int m=(l+r)>>1;
//左右遞迴
Build(ls);
Build(rs);
//更新資訊
PushUp(rt);
}
//點修改,使A[L]+=c
void Update1(int L,int c,int l,int r,int rt)
{
if(l==r){//到達葉節點,修改
sum[rt]+=c;
return;
}
int m=(l+r)>>1;
//根據條件判斷往左子樹呼叫還是往右子樹呼叫
if(L<=m)
Update1(L,c,ls);
else
Update1(L,c,rs);
PushUp(rt);//子節點更新了,本結點也需要更新
}
//下推標記函式
void PushDown(int rt,int ln,int rn)
{
//ln,rn為左右子樹的數量
if(add[rt]){
//下推標記
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
//修改子結點的sum是之與對應的add相對應
sum[rt<<1]+=add[rt]*ln;
sum[rt<<1|1]+=add[rt]*rn;
//清除本結點標記
add[rt]=0;
}
}
//區間修改
void Update2(int L,int R,int C,int l,int r,int rt)
{
if(L<=l&&r<=R){//如果本區間完全在操作區間[L,R]以內
sum[rt]+=C*(r-l+1);//更新數字和,向上保持正確
add[rt]+=C;//增加add標記,表示本區間的sum正確
return;
}
int m=(l+r)>>1;
PushDown(rt,m-l+1,r-m);//下推標記
//判斷左右子樹跟[L,R]有無交集,有交集才遞迴
if(L<=m)
Update2(L,R,C,ls);
if(R>m)
Update2(L,R,C,rs);
PushUp(rt);//更新本結點資訊
}
//區間查詢函式
int Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)//在區間內,直接返回
return sum[rt];
int m=(l+r)>>1;
//下推標記,否則sum可能不正確
PushDown(rt,m-l+1,r-m);
//累計答案
int ans=0;
if(L<=m)
ans+=Query(L,R,ls);
if(R>m)
ans+=Query(L,R,rs);
return ans;
}
int main()
{
n=100;
for(int i=1;i<=n;i++)
a[i]=i;
//建樹
Build(1,n,1);
int ans=Query(1,100,1,n,1);
printf("%d\n",ans);
return 0;
}
相關文章
- 關於線段樹基礎
- 線段樹維護區間等差數列
- Java 演算法-區間求和I(線段樹)Java演算法
- D 區間求和 [數學 樹狀陣列]陣列
- (hdu 1754) I Hate It(線段樹基礎,單點更新)
- 線段樹+差分——【模板】樹狀陣列2陣列
- hdu 4836 The Query on the Tree(線段樹or樹狀陣列)陣列
- HDU 1556 Color the ball(線段樹|樹狀陣列)陣列
- 樹狀陣列基礎陣列
- 線~段~樹
- 線段樹
- BZOJ4636: 蒟蒻的數列(動態開節點線段樹)
- 線段樹 hate it
- 【模版】線段樹
- 01 線段樹
- 線段樹--RMQMQ
- 李超線段樹
- 線段樹模板
- light oj 1080 線段樹和樹狀陣列陣列
- HDU1754 I Hate It 【線段樹基礎:點修改+區間查詢】
- 【Leetcode每日一題】327. 區間和的個數(線段樹/樹狀陣列)LeetCode每日一題陣列
- ut.cpp 最大線段並減線段交 [線段樹]
- 線段樹筆記筆記
- 線段樹入門
- 權值線段樹
- 線段樹進階
- 等比數列求和技巧(公式+倍增)公式
- HDU1698 Just a Hook【線段樹基礎:區間修改+區間查詢】Hook
- 線段樹(毒瘤)總結
- 線段樹模板總結
- 深入理解線段樹
- 線段樹入門理解
- 線段樹(超詳解)
- 第二課——線段樹
- 線段樹簡單思路
- 線段樹擴充套件套件
- 線段樹 transformation——hdu 4578ORM
- 可持久化線段樹持久化