#include<bits/stdc++.h>
using namespace std;
//#define int long long
// 记得开 long long
int n,Q;
const int mod=998244353;
struct Matrix{
int n,m;
long long z[5][5];
Matrix(){
n=0;
m=0;
memset(z,0,sizeof z);
}
};
struct Segment_tree{
Matrix a,tag;
}Tree[1000005];
struct Ball{
long long u,v,w;
}ball[250005];
Matrix operator*(const Matrix &m1,const Matrix &m2){
Matrix m3;
m3.n=m1.n;
m3.m=m2.m;
for(int i=0;i<=m3.n;i++){
for(int j=0;j<=m3.m;j++){
for(int k=0;k<=m1.m;k++){
m3.z[i][j]+=m1.z[i][k]%mod*m2.z[k][j]%mod;
m3.z[i][j]%=mod;
}
}
}
return m3;
}
int ls(int p){return p*2;}
int rs(int p){return p*2+1;}
void pushdown(int p,int l,int r){
if(l!=r){
Tree[ls(p)].tag=Tree[ls(p)].tag*Tree[p].tag;
Tree[ls(p)].a=Tree[p].tag*Tree[ls(p)].a;
Tree[rs(p)].tag=Tree[rs(p)].tag*Tree[p].tag;
Tree[rs(p)].a=Tree[p].tag*Tree[rs(p)].a;
}
for(int i=1-1;i<=5-1;i++){
for(int j=1-1;j<=5-1;j++){
if(i==j)Tree[p].tag.z[i][j]=1;
else Tree[p].tag.z[i][j]=0;
}
}
}
void pushup(int p){
Tree[p].a.z[1-1][1-1]=((Tree[ls(p)].a.z[1-1][1-1]%mod)+(Tree[rs(p)].a.z[1-1][1-1]%mod))%mod;
Tree[p].a.z[2-1][1-1]=((Tree[ls(p)].a.z[2-1][1-1]%mod)+(Tree[rs(p)].a.z[2-1][1-1]%mod))%mod;
Tree[p].a.z[3-1][1-1]=((Tree[ls(p)].a.z[3-1][1-1]%mod)+(Tree[rs(p)].a.z[3-1][1-1]%mod))%mod;
}
void Build_tree(int p,int l,int r){
if(l>r)return;
Tree[p].a.n=5-1;
Tree[p].a.m=1-1;
Tree[p].tag.n=5-1;
Tree[p].tag.m=5-1;
Tree[p].tag.z[1-1][1-1]=1;
Tree[p].tag.z[2-1][2-1]=1;
Tree[p].tag.z[3-1][3-1]=1;
Tree[p].tag.z[4-1][4-1]=1;
Tree[p].tag.z[5-1][5-1]=1;
Tree[p].a.z[5-1][1-1]=1;
Tree[p].a.z[4-1][1-1]=r-l+1;
if(l==r){
Tree[p].a.z[1-1][1-1]=ball[l].u%mod;
Tree[p].a.z[2-1][1-1]=ball[l].v%mod;
Tree[p].a.z[3-1][1-1]=ball[l].w%mod;
return;
}
int mid=(l+r)/2;
Build_tree(ls(p),l,mid);
Build_tree(rs(p),mid+1,r);
pushup(p);
}
bool check1(int l1,int r1,int l2,int r2){
if(l1>=l2&&l1<=r2)return true;
if(r1>=l2&&r1<=r2)return true;
if(l2>=l1&&l2<=r1)return true;
if(r2>=l1&&r2<=r1)return true;
return false;
}
void Amend(int p,int l,int r,int ql,int qr,Matrix change){
if(l>r||ql>qr)return;
if(l>=ql&&r<=qr){
/* printf("p:%d l:%d r:%d ql:%d qr:%d\n",p,l,r,ql,qr);
puts("a1:");
for(int i=1;i<=5;i++){
printf("%d\n",Tree[p].a.z[i][1]);
}*/
Tree[p].a=change*Tree[p].a;
/* puts("a2:");
for(int i=1;i<=5;i++){
printf("%d\n",Tree[p].a.z[i][1]);
} */
Tree[p].tag=Tree[p].tag*change;
return;
}
pushdown(p,l,r);
int mid=(l+r)/2;
if(check1(l,mid,ql,qr))Amend(ls(p),l,mid,ql,qr,change);
if(check1(mid+1,r,ql,qr))Amend(rs(p),mid+1,r,ql,qr,change);
pushup(p);
}
pair<long long,pair<long long,long long> >Query(int p,int l,int r,int ql,int qr){
if(l>r||ql>qr)return {0,{0,0}};
if(l>=ql&&r<=qr){
return {Tree[p].a.z[1-1][1-1]%mod,{Tree[p].a.z[2-1][1-1]%mod,Tree[p].a.z[3-1][1-1]%mod}};
}
pushdown(p,l,r);
pair<long long,pair<long long,long long> > res={0,{0,0}};
pair<long long,pair<long long,long long> > add={0,{0,0}};
int mid=(l+r)/2;
if(check1(l,mid,ql,qr)){
add=Query(ls(p),l,mid,ql,qr);
res.first+=add.first%mod;
res.first%=mod;
res.second.first+=add.second.first%mod;
res.second.first%=mod;
res.second.second+=add.second.second%mod;
res.second.second%=mod;
add={0,{0,0}};
}
if(check1(mid+1,r,ql,qr)){
add=Query(rs(p),mid+1,r,ql,qr);
res.first+=add.first%mod;
res.first%=mod;
res.second.first+=add.second.first%mod;
res.second.first%=mod;
res.second.second+=add.second.second%mod;
res.second.second%=mod;
}
return res;
}
Matrix change;
signed main(){
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld%lld",&ball[i].u,&ball[i].v,&ball[i].w);
ball[i].u%=mod;
ball[i].v%=mod;
ball[i].w%=mod;
}
Build_tree(1,1,n);
scanf("%d",&Q);
while(Q--){
int opt,l,r;
long long v;
scanf("%d%d%d",&opt,&l,&r);
if(opt>=4&&opt<=6)scanf("%lld",&v);
change.n=4;
change.m=4;
for(int i=0;i<=4;i++){
for(int j=0;j<=4;j++){
if(i==j)change.z[i][j]=1;
else change.z[i][j]=0;
}
}
if(opt==1){
change.z[1-1][2-1]=1;
Amend(1,1,n,l,r,change);
}
else if(opt==2){
change.z[2-1][3-1]=1;
Amend(1,1,n,l,r,change);
}
else if(opt==3){
change.z[3-1][1-1]=1;
Amend(1,1,n,l,r,change);
}
else if(opt==4){
change.z[1-1][4-1]=v%mod;
Amend(1,1,n,l,r,change);
}
else if(opt==5){
change.z[2-1][2-1]=v%mod;
Amend(1,1,n,l,r,change);
}
else if(opt==6){
change.z[3-1][3-1]=0;
change.z[3-1][4-1]=v%mod;
Amend(1,1,n,l,r,change);
}
else{
auto ans=Query(1,1,n,l,r);
printf("%lld %lld %lld\n",ans.first%mod,ans.second.first%mod,ans.second.second%mod);
}
}
}
/*
[1 0 0 0 0] [A]
[0 1 0 0 0] [B]
[0 0 1 0 0] × [C]
[0 0 0 1 0] [l]
[0 0 0 0 1] [1]
3
1 2 3
4 2 1
5 3 2
6
7 2 3
1 1 3
2 2 2
6 1 2 4
4 2 3 16
7 2 3
1
8 10 1
2
5 1 1 5
7 1 1
*/
这份代码只要 m 一大就会莫名其妙 WA.
求调。