小林是個程式媛,不可避免地康娜對這種人類的「魔法」產生了濃厚的興趣,於是小林開始教她oi。
今天康娜學習了一種叫做線段樹的神奇魔法,這種魔法可以維護一段區間的資訊,是非常厲害的東西。康娜試著寫了一棵維護區間和的線段樹。由於她不會打標記,因此所有的區間加操作她都是暴力修改的。具體的**如下:
struct segment_tree
inline
void
build
(int o,
int l,
int r)
int mid=
(l+r)
>>1;
build
(lson,l,mid)
;build
(rson,mid+
1,r)
;pushup
(o);
}inline
void
change
(int o,
int l,
int r,
int q,
int v)
int mid=
(l+r)
>>1;
if(q<=mid)
change
(lson,l,mid,q,v)
;else
change
(rson,mid+
1,r,q,v)
;pushup
(o);
}}t;
在修改時,她會這麼寫:
for
(int i=l;i<=r;i++
)t.change(1
,1,n,i,addv)
;
顯然,這棵線段樹每個節點有乙個值,為該節點管轄區間的區間和。
康娜是個愛思考的孩子,於是她突然想到了乙個問題:
1 ≤n
,m≤1
061 \leq n,m \leq 10^6
1≤n,m≤
106−
1000≤a
i,x≤
1000
-1000 \leq a_i,x \leq 1000
−1000≤
ai,
x≤10
00對於本題,我們有乙個最樸素的想法就是對每一層求乙個和,乘上到達這一層的概率,即 12d
ep−1
\frac}
2dep−1
1,但這樣是無法比較快速的應對修改操作的
基於這種思路,我們換個思考的方向,即思考乙個 iii
顯然包含 i
ii 的塊是連續的,如下圖:
對於包含 2
22 下標的塊,一定是連續的
而他所做的貢獻就是上圖標註的
所以現在我們只需要知道每乙個下標 i,i
∈[1,
n]i,i\in [1,n]
i,i∈[1
,n],它對應的葉節點的深度是多少
所以為了實現這一目標,我們來單獨去求這個東西:
求深度是可以用乙個搜尋來解決的,但是我們要快,乙個搜尋是不夠的
那麼優化搜尋的方法是什麼?
記憶化!
對的,我們在這裡有乙個比較好玩的性質,對於每乙個長度相同的區間,這兩個區間中相對應的兩個下標 i,j
i,ji,
j 到這兩個下標的最深深度距離是一樣的
可能有點抽象,我們舉個栗子:
上圖中第 2
22 層的 [1,
3][1,3]
[1,3
] 和 [4,
6][4,6]
[4,6
],區間長度一樣
那麼[ 1,
3][1,3]
[1,3
]區間中的第 2
22 個數也就是 2
22,它到[2,
2][2,2]
[2,2
]的距離是 222;
[ 4,
6][4,6]
[4,6
]區間中的第 2
22 個數也就是 5
55,它到[5,
5][5,5]
[5,5
]的距離也是 222;
當然,我們多找幾個來舉例,也是一樣的
也就是說我們是可以通過這種方法實現記憶化
void
dfs(
int l,
int r,
int sum)
return;}
if(l==r)
int mid=
(l+r)
>>1;
dfs(l,mid,sum+1)
;dfs
(mid+
1,r,sum+1)
; s1[r-l+1]
=l; s2[r-l+1]
=sum;
mem[r-l+1]
=true
;}
處理好了深度,剩下的事情就真的簡單了,乙個字首和,ove
rover
over
#include
#include
using
namespace std;
const
int maxn=
1000005
;int s1[maxn]
;int s2[maxn]
;long
long s[maxn]
;bool mem[maxn]
;long
long pre[maxn]
;int dep[maxn]
,pre_d[maxn]
;int w;
void
dfs(
int l,
int r,
int sum)
return;}
if(l==r)
int mid=
(l+r)
>>1;
dfs(l,mid,sum+1)
;dfs
(mid+
1,r,sum+1)
; s1[r-l+1]
=l; s2[r-l+1]
=sum;
mem[r-l+1]
=true;}
intmain()
for(
int i=
1;i<=n;i++
)// for(int i=1;i<=n;i++)
long
long ans=0;
for(
int i=
1;i<=n;i++
)for
(int i=
1;i<=m;i++
)return0;
}
洛谷 P3924 康娜的線段樹 解題報告
小林是個程式媛,不可避免地康娜對這種人類的 魔法 產生了濃厚的興趣,於是小林開始教她 oi 今天康娜學習了一種叫做線段樹的神奇魔法,這種魔法可以維護一段區間的資訊,是非常厲害的東西。康娜試著寫了一棵維護區間和的線段樹。由於她不會打標記,因此所有的區間加操作她都是暴力修改的。具體的 如下 struct...
線段樹 題解
nyoj 1068 題目鏈結 題目意思 典型的線段樹,插線問線.不過多了乙個,a 操作某乙個區間乙個數整體加上乙個數 s 操作查詢某乙個區間的總和,q 操作,查詢這個區間有多少個奇數.下面是 線段樹延遲更新,奇數的個數更新時注意 如果變化的是奇數,那麼 現在區間奇數個數 區間長度 原本區間的奇數個數...
題解 線段樹 關於時間
這是本蒟蒻的原創題 確實很簡單 本蒟蒻loj賬號diogenes 本題的難點在於每個操作會重複多次。核心思想是把第t秒的操作提前到第一秒,再減去多餘的部分。有一種構造方法 ad d i.j add i.j 表示區間 i j i,j 需要加的值。de l i.j del i.j 表示區間 i j i,...