如題,已知乙個數列,你需要進行下面兩種操作:
1.將某區間每乙個數加上x
2.將某區間每乙個數乘上x
3.求出某區間每乙個數的和
輸入格式:
第一行包含三個整數n、m、p,分別表示該數列數字的個數、操作的總個數和模數。
第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。
接下來m行每行包含3或4個整數,表示乙個操作,具體如下:
操作1: 格式:1 x y k 含義:將區間[x,y]內每個數乘上k
操作2: 格式:2 x y k 含義:將區間[x,y]內每個數加上k
操作3: 格式:3 x y 含義:輸出區間[x,y]內每個數的和對p取模所得的結果
輸出格式:
輸出包含若干行整數,即為所有操作3的結果。
輸入樣例#1:
5 5 38輸出樣例#1:1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4
17時空限制:1000ms,128m2
資料規模:
對於30%的資料:n<=8,m<=10
對於70%的資料:n<=1000,m<=10000
對於100%的資料:n<=100000,m<=100000
(資料已經過加強^_^)
樣例說明:
故輸出應為17、2(40 mod 38=2)
(模板題敲bi半天,結果在區域性變數掛了,qaq)
1 #include2 #include3 #include4 #include5#define maxn 100005
6#define ll long long
7#define ll l,mid,rt<<1
8#define rr mid+1,r,rt<<1|1
9using
namespace
std;
10 ll n,m,mod,a[maxn],add[maxn<<2],mul[maxn<<2],sum[maxn<<2
];11
ll read()
14while(ch>='
0'&&ch<='9')
15return x*f;16}
17void
build(ll l,ll r,ll rt)
23 ll mid=(l+r)>>1
;24 build(l,mid,rt<<1);build(mid+1,r,rt<<1|1
);25 sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;26}
27void
pushdown(ll rt,ll k)
36void
add(ll ql,ll qr,ll v,ll l,ll r,ll rt)
42 pushdown(rt,r-l+1
);43 ll mid=(l+r)>>1;44
if(ql<=mid) add(ql,qr,v,ll);
45if(mid
46 sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;47}
48void
mul(ll ql,ll qr,ll v,ll l,ll r,ll rt)
55 pushdown(rt,r-l+1
);56 ll mid=(l+r)>>1;57
if(ql<=mid) mul(ql,qr,v,ll);
58if(mid
59 sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;60}
61ll query(ll ql,ll qr,ll l,ll r,ll rt)
71int
main()
81if(q==2)85
if(q==3)89
}90return0;
91 }
luogu3373 模板 線段樹 2
題面 已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 題解區間修改 區間查詢。維護兩個lazytag include include using namespace std const int maxn 100010 type...
Luogu3373 模板 線段樹 2
不寫線段樹,就是要分塊!同樣需要打標記 在任何時候,a i mul times a i add bel i 表示 i 屬於哪一塊,a i 表示第 i 個位置的真實值 但是由於標記都是整塊整塊打上去的,無法單點修改,本來可能還可以利用逆元強行修改,問題是 p 571373 不是質數,那麼如何處理零散的...
luogu3373 模板 線段樹2
題目大意 已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 本線段樹的標記是個二元組 add和mul,其代表將乙個線段中的每乙個點乘以mul再加add。設區間長度為x,原來區間和為sum。如果兩個標記要疊加,標記疊加前區間上的和...