有乙個長度為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表示序列長度和操作個數。
第二行n個非負整數,表示序列。
接下來q行每行輸入乙個操作i a b c或者 r a b或者q a b c意義如題目描述。
對於每個詢問,輸出選出c個數相乘的所有方案的和mod19940417的值。
5 51 2 3 4 5
i 2 3 1
q 2 4 2
r 1 5
i 1 3 -1
q 1 5 1
4019940397
題解:線段樹。懶得打題解,放張圖吧。
**無腦longlong
#include#include#include#include#includeusing namespace std;
#define mod 19940417
#define ll long long
const ll n=60100;
ll n,q;
struct nodesa[n*4];
ll c[n][36],aa[n];
ll p1[n*4],d1[n*4];//標記相反數,加數
node update(node a,node b)
void built(ll k,ll l,ll r)
ll mid=(l+r)>>1;
built(k<<1,l,mid);built(k<<1|1,mid+1,r);
sa[k]=update(sa[k<<1],sa[k<<1|1]);
}void get_mark(ll k,ll l,ll r,ll v,ll p)
if(v)
sa[k].sum[i]=temp;}}
d1[k]=(d1[k]+v+mod)%mod;
}void pushdown(ll k,ll l,ll r)
void insert(ll k,ll l,ll r,ll l1,ll rr,long long v,ll pp)
if (p1[k]||d1[k]) pushdown(k,l,r);
if (l1<=mid) insert(k<<1,l,mid,l1,rr,v,pp);
if (rr>mid) insert(k<<1|1,mid+1,r,l1,rr,v,pp);
sa[k]=update(sa[k<<1],sa[k<<1|1]);
} node query(ll k,ll l,ll r,ll l1,ll rr)
int main()
for(ll i=1;i<=n;i++)
scanf("%lld",&aa[i]);built(1,1,n);
char s[6];
ll a,b,c;
for(ll i=1;i<=q;i++)
if(s[0]=='r')
if(s[0]=='q')
} }
BZOJ2962 序列操作
題目大意 給定n個數,要求支援區間加,區間取相反數,區間查詢任意選c c 20 個數的所有方案中乘積的和 和維護k次方的和很像,想要維護選c個數,就要把選1 c個數的方案全部維護出來 這樣當合併兩個區間的時候 pushup 只需要列舉左右區間分別取了幾個數即可 現在考慮兩種修改操作 1.區間取相反數...
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...
BZOJ 2962 序列操作
有乙個長度為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表示序列長度和操作個數。第...