# 【Atcoder F - Cumulative Cumulative Cumulative Sum】线段树

2022-06-24 11:00:45  阅读：9  来源： 互联网

```import java.util.Scanner;

class Main {
//  static long[] A2 ;//i^2*AI
//  static long[] A1;//i*Ai;
static long[] A;   //Ai;
static long[] f2;
static long[] f1;
static long[] f0;
static long power2;

static long MOD = 998244353l;

public static long power(long a,long power){
if(power == 1){
return a;
}
if(power == 0){
return 1;
}
long x = power(a,power/2);
if(power %2 == 0){
return x*x%MOD;
}
return (x*x%MOD)*a%MOD;
}

public static void main(String[] args) {
int n,q;
Scanner in = new Scanner(System.in);
n = in.nextInt();
q = in.nextInt();
A = new long[n+1];
//   A2 = new long[n+1];
//   A1 = new long[n+1];

f0 = new long[4*n+1];
f1 = new long[4*n+1];
f2 = new long[4*n+1];

power2 = power(2,MOD -2);
for (int i = 1; i <=n; i++) {
A[i] = in.nextLong();
//       A1[i] = A[i]*i%MOD;
//      A2[i] = A[i]*i%MOD*i%MOD;
}
//构造树
buildTree(1,1,n);
//查询
for (int i = 0; i < q; i++) {
int op = in.nextInt();
if(op == 1){
int x = in.nextInt();
long v = in.nextInt();
updateTree(1,1,n,x,v);
}else{
int x = in.nextInt();
long ans = query(1,1,n,1,x,x);
System.out.println(ans);
}
}
}

public static long query(int index,int l,int r,int L,int R,int x){
if(l == L && r== R){
long ans = (f2[index] - f1[index]*(2*x+3)%MOD + f0[index]*(x+1)%MOD*(x+2)%MOD + MOD)%MOD*power2%MOD;
ans = ans % MOD;
ans = (ans+ MOD) % MOD;
return ans;
}
int mid =  (l+r) / 2;
if(R<=mid){
long ans = query(index*2,l,mid,L,R,x);
return ans;
}else{
if(L>mid){
return query(index*2+1,mid+1,r,L,R,x);
}else{
long ans = query(index*2,l,mid,L,mid,x);
ans +=query(index*2+1,mid+1,r,mid+1,R,x);
ans %=MOD;
return ans;
}
}
}

public static void updateTree(int index,int l,int r,int x,long v){
if( l==r) {
A[x] = v;
f0[index] = v;
f1[index] = v*l%MOD;
f2[index] = v*l%MOD*l%MOD;
return;
}
int mid = (l+r)/2;
if(x<=mid){
//更新左边
updateTree(index*2,l,mid,x,v);
}else{
updateTree(index*2+1,mid+1,r,x,v);
}

f0[index] =  f0[2*index] + f0[2*index+1];
f0[index] %=MOD;
f1[index] = f1[2*index] + f1[2*index+1];
f1[index] %= MOD;
f2[index] = f2[2*index] + f2[2*index+1];
f2[index] %=MOD;
}

public static void buildTree(int index,int l,int r){
if( l == r){
f0[index] = A[l];
f1[index] = A[l]*l%MOD;
f2[index] = A[l]*l%MOD*l%MOD;
return;
}
int mid = (l+r)/2;

buildTree(2*index,l,mid);
buildTree(2*index+1,mid+1,r);

f0[index] =  f0[2*index] + f0[2*index+1];
f0[index] %=MOD;
f1[index] = f1[2*index] + f1[2*index+1];
f1[index] %= MOD;
f2[index] = f2[2*index] + f2[2*index+1];
f2[index] %=MOD;
}
}```