代码
#include<bits/stdc++.h>
#define mod 998244353
using namespace std;
int n,m;
struct mat{
int num[4][4];
mat() {memset(num,0,sizeof(num));}
inline void clear(){
memset(num,0,sizeof(num));
}
inline void init(){
num[0][0]=num[1][1]=num[2][2]=num[3][3]=1;
}
mat(const int a[][4]){
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
num[i][j]=a[i][j];
}
}
}
mat operator + (const mat &b) const{
mat r;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
r.num[i][j]=(1ll*num[i][j]+b.num[i][j])%mod;
}
}
return r;
}
mat operator * (const mat &b) const{
mat r;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
r.num[i][j]=(r.num[i][j]+(1ll*num[i][0]*b.num[0][j])%mod)%mod;
r.num[i][j]=(r.num[i][j]+(1ll*num[i][1]*b.num[1][j])%mod)%mod;
r.num[i][j]=(r.num[i][j]+(1ll*num[i][2]*b.num[2][j])%mod)%mod;
r.num[i][j]=(r.num[i][j]+(1ll*num[i][3]*b.num[3][j])%mod)%mod;
}
}
return r;
}
}a[260005],A[4],B[4];
struct Tree{
int l,r,siz;
mat val,tag;
}t[1100005];
#define ls(x) x<<1
#define rs(x) x<<1|1
void pushup(int x){
t[x].val=(t[ls(x)].val+t[rs(x)].val);
}
void pushdown(int x){
t[ls(x)].val=(t[x].tag*t[ls(x)].val);
t[rs(x)].val=(t[x].tag*t[rs(x)].val);
t[ls(x)].tag=(t[ls(x)].tag*t[x].tag);
t[rs(x)].tag=(t[rs(x)].tag*t[x].tag);
t[x].tag.clear();
t[x].tag.init();
}
void build(int x,int l,int r){
t[x].l=l,t[x].r=r,t[x].siz=r-l+1;
t[x].tag.init();
if(l==r){
t[x].val=a[l];
return ;
}
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
pushup(x);
}
void add(int x,int ll,int rr,mat k){
if(t[x].l>rr||t[x].r<ll) return;
if(t[x].l>=ll&&t[x].r<=rr){
t[x].val=(t[x].val*k);
t[x].tag=(t[x].tag*k);
return;
}
pushdown(x);
add(ls(x),ll,rr,k);
add(rs(x),ll,rr,k);
pushup(x);
}
mat query(int x,int ll,int rr){
mat i;
if(t[x].l>rr||t[x].r<ll) return i;
if(t[x].l>=ll&&t[x].r<=rr) return t[x].val;
pushdown(x);
return query(ls(x),ll,rr)+query(rs(x),ll,rr);
}
int main(){
A[0].init();A[1].init();A[2].init();
B[0].init();B[1].init();B[2].init();
A[0].num[1][0]=A[1].num[2][1]=A[2].num[0][2]=1;
B[2].num[2][2]=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].num[0][0],&a[i].num[0][1],&a[i].num[0][2]);
a[i].num[0][3]=1;
}
build(1,1,n);
scanf("%d",&m);
int opt,l,r;
int v;
while(m--){
scanf("%d%d%d",&opt,&l,&r);
if(opt<=3) add(1,l,r,A[opt-1]);
else if(opt<=6) {
scanf("%d",&v);
B[0].num[3][0]=B[1].num[1][1]=B[2].num[3][2]=v;
add(1,l,r,B[opt-4]);
}
else{
mat ans=query(1,l,r);
printf("%d %d %d\n",ans.num[0][0]%mod,ans.num[0][1]%mod,ans.num[0][2]%mod);
}
}
return 0;
}