原链接
题意简述
给定一个数列,要支持区间加,乘,赋值,和区间求一次,二次,三次方和。
数据
输入
第一行两个正整数 n , m n,m n,m。 n n n表示序列长度, m m m表示操作数。一个操作包含四个整数, o , l , r , x o,l,r,x o,l,r,x, o = 1 , 2 , 3 o=1,2,3 o=1,2,3分别对应在 [ l , r ] [l,r] [l,r]内加/乘/改为 x x x。 o = 4 o=4 o=4表示询问 [ l , r ] [l,r] [l,r]之间的 x x x次方和(如果 o = 4 o=4 o=4,保证 x < = 3 x<=3 x<=3)。多组数据,如果 n = m = 0 n=m=0 n=m=0表示结束。
输出
对于每个 o = 4 o=4 o=4的询问,输出答案。
样例
输入
5 5
3 3 5 7
1 2 4 4
4 1 5 2
2 2 5 8
4 3 5 3
0 0
输出
307
7489
思路
这个题思路很明显,就是用线段树维护一下。就是代码量比较大,思维量也比较大。
首先我们要维护三个 l a z y t a g lazytag lazytag,三个值,三个 l a z y t a g lazytag lazytag分别命名为 a ( 即 a d d i t i o n ) , m ( 即 m u l i p l i c a t i o n ) , c ( 即 c h a n g e ) a(即addition),m(即muliplication),c(即change) a(即addition),m(即muliplication),c(即change),分别表示加标记,乘标记,赋值标记。
三个值分别为 s 1 , s 2 , s 3 s1,s2,s3 s1,s2,s3,表示区间的一次方和,二次方和,三次方和。
当我们对区间进行赋值操作的时候,显然这优先级非常高,会覆盖掉所有的其他标记。此时设我们赋的值是 x x x,长度为 n n n,那么 s 1 = x ∗ n s1=x*n s1=x∗n, s 2 = x 2 ∗ n s2=x^2*n s2=x2∗n, s 3 = x 3 ∗ n s3=x^3*n s3=x3∗n.
当我们对区间进行乘法操作的时候,会对加法标记产生影响。设我们乘了 x x x,原来加标记是 a a a,表示我们加过 a a a,那么现在就要加 a x ax ax。同时,我们的 s 1 = s 1 ∗ x s1=s1*x s1=s1∗x, s 2 = s 2 ∗ x 2 s2=s2*x^2 s2=s2∗x2