首先考虑计算要求的式子,不妨设 l = 1 , r = n l=1,r=n l=1,r=n。
∑ i = 1 n a i k ∏ j ≠ i 1 − a i a j a i − a j \sum_{i=1}^{n}a_i^k\prod_{j\not=i}\frac{1-a_ia_j}{a_i-a_j} ∑i=1naik∏j=iai−aj1−aiaj
= ∑ i = 1 n a i k ∏ j ≠ i 1 a i − a j ∏ j ≠ i ( 1 − a i a j ) =\sum_{i=1}^{n}a_i^k\prod_{j\not=i}\frac{1}{a_i-a_j}\prod_{j\not=i}(1-a_ia_j) =∑i=1naik∏j=iai−aj1∏j=i(1−aiaj)
= ∑ i = 1 n a i k ∏ j ≠ i 1 a i − a j ∑ l = 0 n − 1 [ x n − 1 − l ] ∏ j ≠ i ( x − a i a j ) =\sum_{i=1}^{n}a_i^k\prod_{j\not=i}\frac{1}{a_i-a_j}\sum_{l=0}^{n-1}[x^{n-1-l}]\prod_{j\not=i}(x-a_ia_j) =∑i=1naik∏j=iai−aj1∑l=0n−1[xn−1−l]∏j=i(x−aiaj)
= ∑ i = 1 n a i k ∏ j ≠ i 1 a i − a j ∑ l = 0 n − 1 a i l [ x n − 1 − l ] ∏ j ≠ i ( x − a j ) =\sum_{i=1}^{n}a_i^k\prod_{j\not=i}\frac{1}{a_i-a_j}\sum_{l=0}^{n-1}a_i^l[x^{n-1-l}]\prod_{j\not=i}(x-a_j) =∑i=1naik∏j=iai−aj1∑l=0n−1ail[xn−1−l]∏j=i(x−aj)
= ∑ l = 0 n − 1 ∑ i = 1 n a i k + l ∏ j ≠ i 1 a i − a j [ x n − 1 − l ] ∏ j ≠ i ( x − a j ) =\sum_{l=0}^{n-1}\sum_{i=1}^{n}a_i^{k+l}\prod_{j\not=i}\frac{1}{a_i-a_j}[x^{n-1-l}]\prod_{j\not=i}(x-a_j) =∑l=0n−1∑i=1naik+l∏j=iai−aj1[xn−1−l]∏j=i(x−aj)
= ∑ l = 0 n − 1 ∑ i = 1 n [ x n − 1 − l ] ( a i k + l ∏ j ≠ i 1 a i − a j ) x 0 ∏ j ≠ i ( x − a j ) =\sum_{l=0}^{n-1}\sum_{i=1}^{n}[x^{n-1-l}](a_i^{k+l}\prod_{j\not=i}\frac{1}{a_i-a_j})x^0\prod_{j\not=i}(x-a_j) =∑l=0n−1∑i=1n[xn−1−l](aik+l∏j=iai−aj1)x0∏j=i(x−aj)
= ∑ l = 0 n − 1 ∑ i = 1 n [ x n − 1 − l ] a i k + l ∏ j ≠ i x − a j a i − a j =\sum_{l=0}^{n-1}\sum_{i=1}^{n}[x^{n-1-l}]a_i^{k+l}\prod_{j\not=i}\frac{x-a_j}{a_i-a_j} =∑l=0n−1∑i=1n[xn−1−l]aik+l∏j=iai−ajx−aj
= ∑ l = 0 n − 1 [ x n − 1 − l ] ∑ i = 1 n a i k + l ∏ j ≠ i x − a j a i − a j =\sum_{l=0}^{n-1}[x^{n-1-l}]\sum_{i=1}^{n}a_i^{k+l}\prod_{j\not=i}\frac{x-a_j}{a_i-a_j} =∑l=0n−1[xn−1−l]∑i=1naik+l∏j=iai−ajx−aj
根据拉格朗日插值:
f ( x ) f(x) f(x)是一个过点 ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) 的 函 数 (x_1,y_1),(x_2,y_2),...,(x_n,y_n)的函数 (x1,y1),(x2,y2),...,(xn,yn)的函数
记 M = ∏ i = 1 n ( x − x i ) M=\prod_{i=1}^{n}(x-x_i) M=∏i=1n(x−xi),则
f ( x ) ≡ ∑ i = 1 n y i ∏ j ≠ i x − x j x i − x j ( m o d M ) f(x)\equiv \sum_{i=1}^{n}y_i\prod_{j\not=i}\frac{x-x_j}{x_i-x_j}(mod\space M) f(x)≡∑i=1nyi∏j=ixi−xjx−xj(mod M)
函数 f ( x ) = x k + l f(x)=x^{k+l} f(x)=xk+l过点 ( a 1 , a 1 k + l ) , ( a 2 , a 2 k + l ) , . . . , ( a n , a n k + l ) (a_1,a_1^{k+l}),(a_2,a_2^{k+l}),...,(a_n,a_n^{k+l}) (a1,a1k+l),(a2,a2k+l),...,(an,ank+l)
∴ x k + l ≡ ∑ i = 1 n a i k + l ∏ j ≠ i x − a j a i − a j ( m o d ( x − a 1 ) ( x − a 2 ) . . . ( x − a n ) ) \therefore x^{k+l}\equiv\sum_{i=1}^{n}a_i^{k+l}\prod_{j\not=i}\frac{x-a_j}{a_i-a_j}(mod\space(x-a_1)(x-a_2)...(x-a_n)) ∴xk+l≡∑i=1naik+l∏j=iai−ajx−aj(mod (x−a1)(x−a2)...(x−an))
∴ 原 式 = ∑ l = 0 n − 1 [ x n − 1 − l ] ( x k + l m o d ( x − a 1 ) ( x − a 2 ) . . . ( x − a n ) ) \therefore原式=\sum_{l=0}^{n-1}[x^{n-1-l}](x^{k+l}\mod(x-a_1)(x-a_2)...(x-a_n)) ∴原式=∑l=0n−1[xn−1−l](xk+lmod(x−a1)(x−a2)...(x−an))
注意到 0 ≤ k ≤ 2 0\leq k\leq2 0≤k≤2,且 l ≤ n − 1 l\leq n-1 l≤n−1,所以 k + l ≥ n k+l\geq n k+l≥n的情况不多,分类讨论即可:
1.若 k + l ≤ n − 1 k+l\leq n-1 k+l≤n−1( x k + l x^{k+l} xk+l的次数低于 m o d mod mod的多项式):
原 式 = ∑ l = 1 n − 1 [ x n − 1 − l ] x k + l = ∑ l = 1 n − 1 [ n − 1 − l = k + l ] 原式=\sum_{l=1}^{n-1}[x^{n-1-l}]x^{k+l}=\sum_{l=1}^{n-1}[n-1-l=k+l] 原式=∑l=1n−1[xn−1−l]xk+l=∑l=1n−1[n−1−l=k+l]
解得 l = n − k − 1 2 l=\frac{n-k-1}{2} l=2n−k−1
则当
n
−
k
−
1
≡
0
(
m
o
d
2
)
n-k-1\equiv 0(mod\space 2)
n−k−1≡0(mod 2)且
0
≤
n
−
k
−
1
0\leq n-k-1
0≤n−k−1时原式为1,否则为0,
即当
n
−
k
−
1
≡
1
(
m
o
d
2
)
n-k-1\equiv1(mod\space 2)
n−k−1≡1(mod 2)或
n
=
1
,
k
=
2
n=1,k=2
n=1,k=2时原式为0,否则为1
2.若 k + l ≥ n k+l\geq n k+l≥n:
∵ l ≤ n − 1 \because l\leq n-1 ∵l≤n−1 ∴ k ≥ 1 \therefore k\geq1 ∴k≥1
2.1若 k = 1 k=1 k=1:
此时有 l = n − 1 l=n-1 l=n−1
原
式
=
[
x
0
]
(
x
n
m
o
d
(
x
−
a
1
)
(
x
−
a
2
)
.
.
.
(
x
−
a
n
)
)
原式=[x^0](x^n\mod(x-a_1)(x-a_2)...(x-a_n))
原式=[x0](xnmod(x−a1)(x−a2)...(x−an))
=
[
x
0
]
(
x
n
−
(
x
−
a
1
)
(
x
−
a
2
)
.
.
.
(
x
−
a
n
)
)
=[x^0](x^n-(x-a_1)(x-a_2)...(x-a_n))
=[x0](xn−(x−a1)(x−a2)...(x−an))
=
(
−
1
)
n
+
1
a
1
a
2
.
.
.
a
n
=(-1)^{n+1}a_1a_2...a_n
=(−1)n+1a1a2...an
2.2若 k = 2 k=2 k=2:
此时有 l = n − 2 或 l = n − 1 l=n-2或l=n-1 l=n−2或l=n−1
2.2.1若 l = n − 2 l=n-2 l=n−2:
∵ l ≥ 0 \because l\geq0 ∵l≥0 ∴ n ≠ 1 \therefore n\not=1 ∴n=1
原
式
=
[
x
1
]
(
x
n
m
o
d
(
x
−
a
1
)
(
x
−
a
2
)
.
.
.
(
x
−
a
n
)
)
原式=[x^1](x^n\mod(x-a_1)(x-a_2)...(x-a_n))
原式=[x1](xnmod(x−a1)(x−a2)...(x−an))
=
[
x
1
]
(
x
n
−
(
x
−
a
1
)
(
x
−
a
2
)
.
.
.
(
x
−
a
n
)
)
=[x^1](x^n-(x-a_1)(x-a_2)...(x-a_n))
=[x1](xn−(x−a1)(x−a2)...(x−an))
=
(
−
1
)
n
∑
i
=
1
n
∏
j
≠
i
a
j
=(-1)^n\sum_{i=1}^{n}\prod_{j\not=i}a_j
=(−1)n∑i=1n∏j=iaj
2.2.2若 l = n − 1 l=n-1 l=n−1:
原
式
=
[
x
0
]
(
x
n
+
1
m
o
d
(
x
−
a
1
)
(
x
−
a
2
)
.
.
.
(
x
−
a
n
)
)
原式=[x^0](x^{n+1}\mod(x-a_1)(x-a_2)...(x-a_n))
原式=[x0](xn+1mod(x−a1)(x−a2)...(x−an))
=
[
x
0
]
(
x
n
+
1
−
(
x
+
a
1
+
a
2
+
.
.
.
+
a
n
)
⏟
大
除
法
得
出
(
x
−
a
1
)
(
x
−
a
2
)
.
.
.
(
x
−
a
n
)
)
=[x^0](x^{n+1}-\begin{matrix}\underbrace{(x+a_1+a_2+...+a_n)}\\大除法得出\end{matrix}(x-a_1)(x-a_2)...(x-a_n))
=[x0](xn+1−
(x+a1+a2+...+an)大除法得出(x−a1)(x−a2)...(x−an))
=
(
−
1
)
n
+
1
∑
i
=
1
n
a
i
∏
j
=
1
n
a
j
=(-1)^{n+1}\sum_{i=1}^{n}a_i\prod_{j=1}^{n}a_j
=(−1)n+1∑i=1nai∏j=1naj
当 n = 1 , k = 2 n=1,k=2 n=1,k=2时,两处的特判可以相互抵消,于是可以不需要特判。
于是只要维护 ∑ i = 1 n a i \sum_{i=1}^{n}a_i ∑i=1nai , ∏ i = 1 n a i \prod_{i=1}^{n}a_i ∏i=1nai , ∑ i = 1 n ∏ j ≠ i a j \sum_{i=1}^{n}\prod_{j\not=i}a_j ∑i=1n∏j=iaj,在区间乘的操作下用线段树解决
#include<iostream>
#include<cstdio>
using namespace std;
const int mod=998244353;
const int N=300010;
int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct Node{
int sum,pro,ans;
Node(){sum=0;pro=1;ans=0;}
Node(int a,int b,int c){sum=a,pro=b,ans=c;}
}t[N<<2];
int n,m,a[N],laz[N<<2];
int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
int dec(int a,int b){return a-b<0?a-b+mod:a-b;}
int mul(int a,int b){return 1ll*a*b%mod;}
int power(int a,int b){
int res=1;
while(b){
if(b&1) res=mul(res,a);
a=mul(a,a);
b>>=1;
}
return res;
}
Node merge(Node a,Node b){
Node c;
c.sum=add(a.sum,b.sum);
c.pro=mul(a.pro,b.pro);
c.ans=add(mul(a.ans,b.pro),mul(a.pro,b.ans));
return c;
}
void pushup(int u){
t[u]=merge(t[u<<1],t[u<<1|1]);
}
void build(int u,int l,int r){
laz[u]=1;
if(l==r){
t[u]=Node(a[l],a[l],1);
return;
}
int mid=(l+r)>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
void modify(int u,int l,int r,int x){
t[u].sum=mul(t[u].sum,x);
t[u].pro=mul(t[u].pro,power(x,r-l+1));
t[u].ans=mul(t[u].ans,power(x,r-l));
laz[u]=mul(laz[u],x);
}
void pushdown(int u,int l,int r){
if(laz[u]!=1){
int mid=(l+r)>>1;
modify(u<<1,l,mid,laz[u]);
modify(u<<1|1,mid+1,r,laz[u]);
laz[u]=1;
}
}
void update(int u,int l,int r,int a,int b,int x){
if(a<=l&&r<=b){
modify(u,l,r,x);
return;
}
pushdown(u,l,r);
int mid=(l+r)>>1;
if(a<=mid) update(u<<1,l,mid,a,b,x);
if(b>mid) update(u<<1|1,mid+1,r,a,b,x);
pushup(u);
}
Node query(int u,int l,int r,int a,int b){
if(a<=l&&r<=b) return t[u];
pushdown(u,l,r);
int mid=(l+r)>>1;
Node res=Node(0,1,0);
if(a<=mid) res=merge(res,query(u<<1,l,mid,a,b));
if(b>mid) res=merge(res,query(u<<1|1,mid+1,r,a,b));
return res;
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
int opt,l,r,k;
while(m--){
opt=read();l=read();r=read();k=read();
if(opt==1)
update(1,1,n,l,r,k);
else{
int d=r-l+1,ans=0;
if(!((d-k-1)&1)) ans++;
Node now=query(1,1,n,l,r);
if(k==1){
if(d&1) ans=add(ans,now.pro);
else ans=dec(ans,now.pro);
}
if(k==2){
if(!(d&1)) ans=add(ans,now.ans);
else ans=dec(ans,now.ans);
if(d&1) ans=add(ans,mul(now.sum,now.pro));
else ans=dec(ans,mul(now.sum,now.pro));
}
printf("%d\n",ans);
}
}
return 0;
}