有乙個長度為n的序列,有三個操作1.i a b c表示將[a,b]這一段區間的元素集體增加c,2.r a b表示將[a,b]區間內所有元素變成相反數,3.q a b c表示詢問[a,b]這一段區間中選擇c個數相乘的所有方案的和mod 19940417的值。
100%的資料n<=50000,q<=50000,初始序列的元素的絕對值<=109,i a b c中保證[a,b]是乙個合法區間,|c|<=109,r a b保證[a,b]是個合法的區間。q a b c中保證[a,b]是個合法的區間1<=c<=min(b-a+1,20)。
計fi為選出i個的答案,那麼顯然有fn=
∑i=0
nfi×
fn−i
f_n=\sum_^nf_i\times f_
fn=∑i
=0n
fi×
fn−i
考慮用線段樹維護這個東西。合併直接c^2卷積,問題在於取反和區間加怎麼搞
觀察這個柿子,我們發現對於n為偶數的情況取反不影響,對於n為奇數的情況直接取反就可以了
考慮怎麼區間加,記區間長度為len,要加上v。容易得到fn=
∑i=0
nfn−
i×vi
×(le
n−n+
ii
)f_n=\sum_^nf_\times v^i\times\binom
fn=∑i
=0n
fn−i
×vi
×(il
en−n
+i)
,即我們列舉選i個v,剩餘n-i個從剩下len-(n-i)個裡面選。實在不行把∏(a
i+v)
\prod(a_i+v)
∏(ai+
v)這個東西拆開也能得到這個結論
然後就可以了。比較難寫,喜聞樂見(我)要卡常
#include
#include
#include
#define rep(i,st,ed) for (register int i=st;i<=ed;++i)
#define drp(i,st,ed) for (register int i=st;i>=ed;--i)
typedef
long
long ll;
const
int mod=
19940417
;const
int n=
50005
;bool rev[n<<2]
;ll c[n][21
],tag[n<<2]
;inline
void
mod(ll &x)
struct wjp
wjp operator
*(wjp b)
const
return ret;
} wjp operator
+(ll v)
const
}return ret;
}} rec[n<<2]
;inline
intread()
void
push_down
(int now)
rev[now]=0
; rev[now<<1]
^=1; rev[now<<1|
1]^=
1;mod(tag[now<<1]
=-tag[now<<1]
);mod(tag[now<<1|
1]=-tag[now<<1|
1]);
}if(tag[now])}
void
modify
(int now,
int tl,
int tr,
int l,
int r,ll v)
else
return;}
push_down
(now)
;int mid=
(tl+tr)
>>1;
if(r<=mid)
modify
(now<<
1,tl,mid,l,r,v)
;else
if(l>mid)
modify
(now<<1|
1,mid+
1,tr,l,r,v)
;else
rec[now]
=rec[now<<1]
*rec[now<<1|
1];}
wjp query
(int now,
int tl,
int tr,
int l,
int r)
void
build
(int now,
int tl,
int tr)
int mid=
(tl+tr)
>>1;
build
(now<<
1,tl,mid)
;build
(now<<1|
1,mid+
1,tr)
; rec[now]
=rec[now<<1]
*rec[now<<1|
1];}
intmain
(void)}
build(1
,1,n);
for(
int opt,l,r,x;m--;)
else
if(opt==
'i')
else
modify(1
,1,n,l,r,
1e9+7)
;}return0;
}
序列操作 BZOJ2962 線段樹
分析 資料範圍表示 c特別的小 c 20 我們可以考慮nlogn c 2的演算法。線段樹維護區間資訊 f i 表示在 l,r 這段區間中選擇i個數相乘的和。因此,我們可以將區間看成乙個點,在pushup的時候用揹包的方式更新父節點。仔細觀察發現這是卷積 剩下的就是一些優化了.附上 include i...
BZOJ2962 序列操作
題目大意 給定n個數,要求支援區間加,區間取相反數,區間查詢任意選c c 20 個數的所有方案中乘積的和 和維護k次方的和很像,想要維護選c個數,就要把選1 c個數的方案全部維護出來 這樣當合併兩個區間的時候 pushup 只需要列舉左右區間分別取了幾個數即可 現在考慮兩種修改操作 1.區間取相反數...
bzoj2962 序列操作
有乙個長度為n的序列,有三個操作1.i a b c表示將 a,b 這一段區間的元素集體增加c,2.r a b表示將 a,b 區間內所有元素變成相反數,3.q a b c表示詢問 a,b 這一段區間中選擇c個數相乘的所有方案的和mod 19940417的值。第一行兩個數n,q表示序列長度和操作個數。第...