bzoj2962 序列操作 線段樹 組合數學

2021-08-28 20:43:12 字數 2850 閱讀 6010

有乙個長度為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表示序列長度和操作個數。第...