分析:
資料範圍表示: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表示序列長度和操作個數。第...