bzoj 2962序列操作

2022-05-02 03:48:08 字數 1973 閱讀 9691

標籤: 線段樹

題目鏈結

給你一串串行,要你維護三個操作:

1.區間加法

2.區間取相反數

3.區間內任意選k個數相乘的積

第三個操作看起來一臉懵逼啊。

其實是可以合併的。

$ c[o].s[i]=\sum_^c[lc].s[j]×c[rc].s[i-j]\(

跟\)c_mn=\sum_n c_ni×c_ $這個等式是乙個道理的吧。

然後想怎麼維護加和取反。

取反比較容易,把取奇數個的答案變成相反數。

加法就稍微複雜一點。

假如p是加上的數,s[i]是區間內取k個數的答案。

\[s[i]=\sum_^k c_^i×s[j]×p^

\](不知道為什麼常數很大,bzoj上43s才過)

#include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define ll long long

#define rep(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)

#define drep(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)

#define erep(i,a) for(int i=start[(a)];i;i=e[i].next)

inline int read()

const int mod=19940417;

const int maxn=1e5+20;

struct node

}};node c[maxn*4];

int n;

int a[maxn],c[maxn][25];

#define lc (o<<1)

#define rc (o<<1 | 1)

#define left lc,l,mid

#define right rc,mid+1,r

void reverse(int o,int l,int r)

void add(int o,int l,int r,ll add) }}

void pushdown(int o,int l,int r)

if(c[o].add) }

void make_tree(int o,int l,int r)

int mid=(l+r)>>1;

make_tree(left);

make_tree(right);

c[o].merge(c[lc],c[rc]);

}int q;

void init()

make_tree(1,1,n);

}void updatea(int ql,int qr,ll x,int o,int l,int r)

int mid=(l+r)>>1;

pushdown(o,l,r);

if(ql<=mid )updatea(ql,qr,x,left);

if(qr>mid)updatea(ql,qr,x,right);

c[o].merge(c[lc],c[rc]);

}void updater(int ql,int qr,int o,int l,int r)

int mid=(l+r)>>1;

pushdown(o,l,r);

if(ql<=mid)updater(ql,qr,left);

if(qr>mid)updater(ql,qr,right);

c[o].merge(c[lc],c[rc]);

}node query(int ql,int qr,int o,int l,int r)

}void doing()

else if(ch=='r')

else

}}int main()

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

bzoj 2962 序列操作

time limit 50 sec memory limit 256 mb submit status discuss 有乙個長度為n的序列,有三個操作1.i a b c表示將 a,b 這一段區間的元素集體增加c,2.r a b表示將 a,b 區間內所有元素變成相反數,3.q a b c表示詢問 a...