//qk_3256
#include<bits/stdc++.h>
using namespace std;

#define int long long

const int p = 998244353;
const int N = 1e5 + 10;
struct tree{
    int sum,pfsum,lt1 = 0,lt2 = 1;//a,m
}t[N<<2];
int a[N];

void pushtaga(int id,int l,int r,int w)
{
    t[id].pfsum += t[id].sum * 2 * w % p + (r - l + 1) * w * w % p;
    t[id].pfsum %= p;
    t[id].sum += (r - l + 1) * w % p;//debug:l,r
    t[id].sum %= p;
    t[id].lt1 += w;
}

void pushtagm(int id,int l,int r,int w)
{
    t[id].pfsum *= w * w % p;
    t[id].pfsum %= p;
    t[id].sum *= w;
    t[id].sum %= p;
    t[id].lt1 *= w,t[id].lt2 *= w;
    t[id].lt1 %= p,t[id].lt2 %= p;
}

void pushtag(int id,int l,int r,int w1,int w2)
{
    t[id].pfsum *= w2 * w2 % p;
    t[id].pfsum %= p; 
    t[id].pfsum += (2 * w2 * t[id].sum % p + (r - l + 1) * w1) % p * w1 % p;
    t[id].pfsum %= p;
    
    t[id].sum *= w2;t[id].sum %= p;t[id].sum += (r - l + 1) * w1 % p;t[id].sum %= p;
    t[id].lt1 *= w2,t[id].lt1 += w1;
    t[id].lt2 *= w2;
    t[id].lt1 %= p,t[id].lt2 %= p;
}

void pushup(int id)
{
    t[id].pfsum = t[id<<1].pfsum + t[id<<1|1].pfsum;
    t[id].pfsum %= p;
    t[id].sum = t[id<<1].sum + t[id<<1|1].sum;
    t[id].sum %= p;
}

void pushdown(int id,int l,int r)
{
    if(t[id].lt1 == 0 && t[id].lt2 == 1) return;
    int mid = (l + r) >> 1;
    pushtag(id<<1,l,mid,t[id].lt1,t[id].lt2);
    pushtag(id<<1|1,mid + 1,r,t[id].lt1,t[id].lt2);
    t[id].lt1 = 0,t[id].lt2 = 1;
}

void build(int id,int l,int r)
{
    if(l == r){
        t[id].sum = a[l];
        t[id].pfsum = a[l] * a[l] % p;
        return;
    }
    int mid = (l + r) >> 1;
    build(id<<1,l,mid);
    build(id<<1|1,mid + 1,r);
    pushup(id);//debug
}

void add(int id,int l,int r,int s,int te,int w){
    if(l == s && r == te){
        pushtaga(id,l,r,w);
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(id,l,r);
    if(te <= mid) add(id<<1,l,mid,s,te,w);
    else if(s > mid) add(id<<1|1,mid + 1,r,s,te,w);
    else{
        add(id<<1,l,mid,s,mid,w);
        add(id<<1|1,mid + 1,r,mid + 1,te,w);
    }
    pushup(id);
}

void multi(int id,int l,int r,int s,int te,int w){
    if(l == s && r == te){
        pushtagm(id,l,r,w);
        return;
    }
    pushdown(id,l,r);
    int mid = (l + r) >> 1;
    if(te <= mid) multi(id<<1,l,mid,s,te,w);
    else if(s > mid) multi(id<<1|1,mid + 1,r,s,te,w);
    else{
        multi(id<<1,l,mid,s,mid,w);
        multi(id<<1|1,mid + 1,r,mid + 1,te,w);
    }
    pushup(id);
}

int query(int id,int l,int r,int s,int te)
{
    if(l == s && r == te) return t[id].sum;
    int mid = (l + r) >> 1;
    pushdown(id,l,r);
    if(te <= mid) return query(id<<1,l,mid,s,te);
    else if(s > mid) return query(id<<1|1,mid + 1,r,s,te);
    else return (query(id<<1,l,mid,s,mid) + query(id<<1|1,mid + 1,r,mid + 1,te)) % p;
}

int queryp(int id,int l,int r,int s,int te)
{
    if(l == s && r == te) return t[id].pfsum;
    int mid = (l + r) >> 1;
    pushdown(id,l,r);
    if(te <= mid) return query(id<<1,l,mid,s,te);
    else if(s > mid) return query(id<<1|1,mid + 1,r,s,te);
    else return (query(id<<1,l,mid,s,mid) + query(id<<1|1,mid + 1,r,mid + 1,te)) % p;
}

signed main(){
    freopen("segtree.in","r",stdin);
    freopen("segtree.out","w",stdout);
    int n,q,k,L,R,W;
    scanf("%lld%lld",&n,&q);
    for(int i = 1;i <= n;i++) scanf("%lld",&a[i]);
    build(1,1,n);
    for(int i = 1;i <= q;i++){
        scanf("%lld%lld%lld",&k,&L,&R);
        if(k == 1){
            scanf("%lld",&W);
            add(1,1,n,L,R,W);
        }
        else if(k == 2){
            scanf("%lld",&W);
            multi(1,1,n,L,R,W);
        }
        else if(k == 3) printf("%lld\n",query(1,1,n,L,R));
        else printf("%lld\n",queryp(1,1,n,L,R));
    }
    return 0;
}

0 条评论

目前还没有评论...