我觉得 nm≤107 这种东西过不去就不是常数的问题了()
#include<iostream>
#define int long long
#define mid (l+r)/2
using namespace std;
const int mod=998244353;
int n,q;
struct Matrix{
int sizx,sizy;
int c[5][5];
};
int a[250005],b[250005],c[250005];
Matrix mul(Matrix A,Matrix B){
Matrix C;
C.sizx=A.sizx;
C.sizy=B.sizy;
for(int i=1;i<=A.sizx;i++){
for(int j=1;j<=B.sizy;j++){
C.c[i][j]=0;
for(int k=1;k<=A.sizy;k++){
C.c[i][j]+=A.c[i][k]*B.c[k][j];
C.c[i][j]%=mod;
}
}
}
return C;
}
Matrix tr[1000005],tag[1000005];
void pushup(int x){
for(int i=1;i<=4;i++){
tr[x].c[i][1]=tr[2*x].c[i][1]+tr[2*x+1].c[i][1];
tr[x].c[i][1]%=mod;
}
}
void build(int x,int l,int r){
if(l==r){
tr[x].sizx=1;
tr[x].sizy=4;
tr[x].c[1][1]=a[l];
tr[x].c[2][1]=b[l];
tr[x].c[3][1]=c[l];
tr[x].c[4][1]=1;
tag[x].sizx=4;tag[x].sizy=4;
for(int i=1;i<=4;i++)tag[x].c[i][i]=1;
return ;
}
build(2*x,l,mid);
build(2*x+1,mid+1,r);
for(int i=1;i<=4;i++)tag[x].c[i][i]=1;
tr[x].sizx=1;
tr[x].sizy=4;
pushup(x);
tag[x].sizx=4;tag[x].sizy=4;
for(int i=1;i<=4;i++)tag[x].c[i][i]=1;
}
void pushdown(int x){
tr[2*x]=mul(tr[2*x],tag[x]);
tr[2*x+1]=mul(tr[2*x+1],tag[x]);
tag[2*x]=mul(tag[2*x],tag[x]);
tag[2*x+1]=mul(tag[2*x+1],tag[x]);
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(i==j)tag[x].c[i][j]=1;
else tr[x].c[i][j]=0;
}
}
}
void update(int x,int l,int r,int from,int to,Matrix A){
if(from<=l&&r<=to){
tr[x]=mul(A,tr[x]);
tag[x]=mul(A,tag[x]);
return ;
}
pushdown(x);
if(from<=mid)update(2*x,l,mid,from,to,A);
if(to>mid)update(2*x+1,mid+1,r,from,to,A);
pushup(x);
}
struct ANS{
int x,y,z;
};
ANS query(int x,int l,int r,int from,int to){
if(from<=l&&r<=to){
return {tr[x].c[1][1],tr[x].c[2][1],tr[x].c[3][1]};
}
ANS ans={0,0,0};
pushdown(x);
if(from<=mid){
ans.x+=query(2*x,l,mid,from,to).x;
ans.y+=query(2*x,l,mid,from,to).y;
ans.z+=query(2*x,l,mid,from,to).z;
}
if(to>mid){
ans.x+=query(2*x+1,mid+1,r,from,to).x;
ans.y+=query(2*x+1,mid+1,r,from,to).y;
ans.z+=query(2*x+1,mid+1,r,from,to).z;
}
return ans;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i]>>c[i];
}
build(1,1,n);
cin>>q;
while(q--){
int opt,l,r,v;
cin>>opt>>l>>r;
Matrix A;
A.sizx=A.sizy=4;
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(i==j)A.c[i][j]=1;
else A.c[i][j]=0;
}
}
if(opt==1)A.c[1][2]=1;
if(opt==2)A.c[2][3]=1;
if(opt==3)A.c[3][1]=1;
if(opt==4){
cin>>v;
A.c[1][4]=v;
}
if(opt==5){
cin>>v;
A.c[2][2]=v;
}
if(opt==6){
cin>>v;
A.c[3][3]=0;A.c[3][4]=v;
}
if(opt<=6)update(1,1,n,l,r,A);
else{
ANS x=query(1,1,n,l,r);
cout<<x.x<<' '<<x.y<<' '<<x.z<<endl;
}
}
return 0;
}