提交记录
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct matrix{
int m[5][5];
matrix operator +(const matrix b){
matrix a;
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
a.m[i][j]=(this->m[i][j]+b.m[i][j])%998244353;
}
}
return a;
}
matrix operator *(const matrix b){
matrix a;
memset(a.m,0,sizeof(a.m));
for(int k=1;k<=4;k++){
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++)
{
a.m[i][j]+=(this->m[i][k]*b.m[k][j]);
a.m[i][j]%=998244353;
}
}
}
return a;
}
void copyMatrix(matrix b) {
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
this->m[i][j]=b.m[i][j];
}
}
}
};
void printmat(matrix x){
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
cout<<x.m[i][j]<<' ';
}
cout<<endl;
}
return ;
}
struct node{
matrix key,lzy;
int l,r;
}tr[1000005];
matrix genemat(int v,int op){
matrix m1;
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
m1.m[i][j]=(i==j);
}
}
if(op==1){
m1.m[2][1]=1;
}
if(op==2){
m1.m[3][2]=1;
}
if(op==3){
m1.m[1][3]=1;
}
if(op==4){
m1.m[4][1]=v;
}
if(op==5){
m1.m[2][2]=v;
}
if(op==6){
m1.m[3][3]=0;
m1.m[4][3]=v;
}
return m1;
}
void build(int c,int l,int r){
tr[c].l=l;
tr[c].r=r;
tr[c].lzy=genemat(0,0);
if(l==r){
for(int i=1;i<=3;i++){
cin>>tr[c].key.m[1][i];
}
tr[c].key.m[1][4]=1;
return;
}
int mid=(l+r)/2;
build(c*2,l,mid);
build(c*2+1,mid+1,r);
tr[c].key.copyMatrix(tr[c*2].key+tr[c*2+1].key);
}
void pushdown(int c){
tr[c*2].key.copyMatrix(tr[c*2].key*tr[c].lzy);
tr[c*2+1].key.copyMatrix(tr[c*2+1].key*tr[c].lzy);
tr[c*2].lzy.copyMatrix(tr[c*2].lzy*tr[c].lzy);
tr[c*2+1].lzy.copyMatrix(tr[c*2+1].lzy * tr[c].lzy);
tr[c].lzy.copyMatrix(genemat(0, 0));
}
void update(int c,int l,int r,int v,int opr){
if(tr[c].l==l&&tr[c].r==r){
tr[c].key.copyMatrix(tr[c].key*genemat(v,opr));
tr[c].lzy.copyMatrix(tr[c].lzy*genemat(v,opr));
return;
}
pushdown(c);
int mid=(tr[c].l+tr[c].r)/2;
if(r<=mid){
update(c*2,l,r,v,opr);
}else if(l>mid){
update(c*2+1,l,r,v,opr);
}else{
update(c*2,l,mid,v,opr);
update(c*2+1,mid+1,r,v,opr);
}
tr[c].key.copyMatrix(tr[c*2].key+tr[c*2+1].key);
}
int query(int c,int l,int r,int ele){
if(tr[c].l==l&&tr[c].r==r){
return tr[c].key.m[1][ele];
}
pushdown(c);
int mid=(tr[c].l+tr[c].r)/2;
if(r<=mid){
return query(c*2,l,r,ele);
}else if(l>mid){
return query(c*2+1,l,r,ele);
}else{
return query(c*2,l,mid,ele) + query(c*2+1,mid+1,r,ele);
}
}
signed main(){
int n;
cin>>n;
build(1,1,n);
int m;
cin>>m;
while(m--){
int op;
cin>>op;
int l,r;
cin>>l>>r;
if(op>=1&&op<=3){
update(1,l,r,114514,op);
}
if(op>=4&&op<=6){
int v;
cin>>v;
update(1,l,r,v,op);
}
if(op==7){
cout<<query(1,l,r,1)<<' '<<query(1,l,r,2)<<' '<<query(1,l,r,3)<<endl;
}
}
return 0;
}