小林是個程式媛,不可避免地康娜對這種人類的「魔法」產生了濃厚的興趣,於是小林開始教她\(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);
顯然,這棵線段樹每個節點有乙個值,為該節點管轄區間的區間和。
康娜是個愛思考的孩子,於是她突然想到了乙個問題:
康娜每次會給你乙個值\(qwq\),保證你求出的概率乘上\(qwq\)是乙個整數。
這個問題太簡單了,以至於聰明的康娜一下子就秒了。
現在她想問問你,您會不會做這個題呢?
第一行整數\(n,m,qwq\)表示線段樹維護的原序列的長度,詢問次數,分母。
第二行\(n\)個數,表示原序列。
接下來\(m\)行,每行三個數\(l,r,x\)表示對區間\([l,r]\)加上\(x\)
共\(m\)行,表示期望的權值和乘上\(qwq\)結果。
對於30%的資料,保證 \(1 \leq n,m \leq 100\)
對於70%的資料,保證 \(1 \leq n,m, \leq 10^\)
對於100%的資料,保證 \(1 \leq n,m \leq 10^6\)
\(-1000 \leq a_i,x \leq 1000\)
其實題目不難,然而我概率期望學的差,還是不怎麼會做。
我們發現,其實每個葉子節點的貢獻的不會變的,則第\(i\)個葉子節點貢獻的次數是它之前的所有包含它的區間的貢獻次數之和。
根據條件概率,每乙個大區間出現的概率都是它的子區間的兩倍,所以我們以最小的區間算做1,統計每個葉子節點的貢獻次數,最後再除以\(\lceil logn \rceil\)即可。
具體實現可以直接模擬建樹統計。
然後我們發現操作只有區間加和全域性詢問。
區間加我們可以通過葉子節點貢獻次數字首和維護全域性偏移量。
複雜度:\(o(nlogn+m)\)
code:
#include #define ll long long
ll max(ll x,ll y)
const ll n=1000010;
ll dat[n],cnt[n],f[n],ans,qaq,n,m,d,dep[n];
void build(ll l,ll r,ll dep)
ll mid=l+r>>1;
build(l,mid,dep+1);
build(mid+1,r,dep+1);
}void init()
{ scanf("%lld%lld%lld",&n,&m,&qaq);
build(1,n,1);
for(ll i=1;i<=n;i++)
{if(dep[i]==d)
cnt[i]=(1<2018.7.21
題解 康娜的線段樹
小林是個程式媛,不可避免地康娜對這種人類的 魔法 產生了濃厚的興趣,於是小林開始教她oi。今天康娜學習了一種叫做線段樹的神奇魔法,這種魔法可以維護一段區間的資訊,是非常厲害的東西。康娜試著寫了一棵維護區間和的線段樹。由於她不會打標記,因此所有的區間加操作她都是暴力修改的。具體的 如下 struct ...
線段樹2 洛谷p3373 線段樹
題目位址 解釋 多了乙個乘法操作,可以考慮優先順序。每次先算乘法。首先,對於乙個區間 和為s 假設已經按 a 乘b進行了操作。值得到的值為 s a b sb ab 假設先乘得到 sb a 這樣相比,add應該還要再乘上乙個b才對,所以,當更新到乙個區間時,為了進行先乘的操作而不讓結果發生變化,應該將...
洛谷 P3372 線段樹 1
今天植樹節,來種一棵線段樹。傳送門如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.求出某區間每乙個數的和 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第 i 個數字表示數列第 i 項的初始值。接下來m行每...