序列操作 BZOJ2962 線段樹

2022-04-30 12:00:12 字數 1308 閱讀 8972

分析:

資料範圍表示:c特別的小(c<20)

我們可以考慮nlogn*c^2的演算法。

線段樹維護區間資訊:f[i]表示在[l,r]這段區間中選擇i個數相乘的和。

因此,我們可以將區間看成乙個點,在pushup的時候用揹包的方式更新父節點。(仔細觀察發現這是卷積)

剩下的就是一些優化了...

附上**:

#include #include #include #include #include #include #include using namespace std;

#define n 50005

#define mod 19940417

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

#define ll long long

int c[n][21],a[n],n,q;

char s[10];

struct node

node operator +(const node &b)

}c.siz=siz+b.siz;

return c;

} void plus(ll x)

}} void rev() }

}tr[n<<2];

void pushup(int rt)

void build(int l,int r,int rt)

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

build(lson);

build(rson);

pushup(rt);

}void pushdown(int rt)

if(tr[rt].add) }

void update(int l,int r,int c,int l,int r,int rt)

pushdown(rt);

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

if(m>=l)update(l,r,c,lson);

if(m>1;

if(m>=l)update_rev(l,r,lson);

if(m>1;

if(m>=r)return query(l,r,lson);

if(mreturn query(l,r,lson)+query(l,r,rson);

}int main()

} for(int i=1;i<=n;i++)

build(1,n,1);

while(q--)

else if(s[0]=='r')

else

}return 0;

}

bzoj2962 序列操作 線段樹 區間卷積

題目大意 給定乙個n個數的正整數序列,m次操作。支援 1.區間加 2.區間取相反數 3.區間求選c個數的乘積和。注釋 1 le n,m le 5 cdot 10 4 1 le c le 20 想法 首先切入點非常明顯,我們發現c只有20。那麼線段樹上的每個節點維護21個值sum pos i 表示在p...

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