- 题解
- 2021-07-11 15:54:19 @
//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 条评论
目前还没有评论...