RT,是在卡不过去了,求大佬帮卡常或验证算法正确性!
#include<bits/stdc++.h>
using namespace std;
const int N=2.5e5+5,mod=998244353;
int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
int getm(int x){return x>mod?x-mod:x;}
struct noi{
int c[5][5],l,r;
noi(){
c[1][1]=c[1][2]=c[1][3]=c[1][4]=0;
c[2][1]=c[2][2]=c[2][3]=c[2][4]=0;
c[3][1]=c[3][2]=c[3][3]=c[3][4]=0;
c[4][1]=c[4][2]=c[4][3]=c[4][4]=0;
}
inline void init(){
c[1][2]=c[1][3]=c[1][4]=0;
c[2][1]=c[2][3]=c[2][4]=0;
c[3][1]=c[3][2]=c[3][4]=0;
c[4][1]=c[4][2]=c[4][3]=0;
c[1][1]=c[2][2]=c[3][3]=c[4][4]=1;
}
noi operator+(const noi &b)const{
noi res;
for(int i=1;i<=4;i++){
res.c[i][1]=(1ll*c[i][1]+b.c[i][1])%mod;
res.c[i][2]=(1ll*c[i][2]+b.c[i][2])%mod;
res.c[i][3]=(1ll*c[i][3]+b.c[i][3])%mod;
res.c[i][4]=(1ll*c[i][4]+b.c[i][4])%mod;
}
return res;
}
noi operator*(const noi &b)const{
noi res;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++){
res.c[i][j]=getm(res.c[i][j]+(1ll*c[i][1]*b.c[1][j])%mod);
res.c[i][j]=getm(res.c[i][j]+(1ll*c[i][2]*b.c[2][j])%mod);
res.c[i][j]=getm(res.c[i][j]+(1ll*c[i][3]*b.c[3][j])%mod);
res.c[i][j]=getm(res.c[i][j]+(1ll*c[i][4]*b.c[4][j])%mod);
}
return res;
}
}a[N<<2],input[N],base[10];
noi sum[N<<2],lazy[N<<2],ans;
inline void pushup(int x){
sum[x]=sum[x<<1]+sum[x<<1|1];
}
inline void build(int now,int l,int r){
lazy[now].init();
a[now].l=l,a[now].r=r;
if(l==r){
sum[now].c[1][1]=input[l].c[1][1];sum[now].c[1][2]=input[l].c[1][2];
sum[now].c[1][3]=input[l].c[1][3];sum[now].c[1][4]=1;
return;
}
int mid=l+r>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
pushup(now);
}
inline void pushdown(int x){
sum[x<<1]=sum[x<<1]*lazy[x];
lazy[x<<1]=lazy[x<<1]*lazy[x];
sum[x<<1|1]=sum[x<<1|1]*lazy[x];
lazy[x<<1|1]=lazy[x<<1|1]*lazy[x];
lazy[x].init();
}
inline void update(int now,int l,int r,noi k){
if(a[now].l>=l&&a[now].r<=r){
sum[now]=sum[now]*k;
lazy[now]=lazy[now]*k;
return;
}
pushdown(now);
int mid=a[now].l+a[now].r>>1;
if(mid>=l)update(now<<1,l,r,k);
if(mid<r)update(now<<1|1,l,r,k);
pushup(now);
}
inline noi query(int now,int l,int r){
if(a[now].l>=l&&a[now].r<=r)return sum[now];
pushdown(now);
int mid=a[now].l+a[now].r>>1;
noi res;
if(mid>=l)res=res+query(now<<1,l,r);
if(mid<r)res=res+query(now<<1|1,l,r);
return res;
}
int main(){
int n(read());
for(int i=1;i<=n;i++)
input[i].c[1][1]=read(),input[i].c[1][2]=read(),input[i].c[1][3]=read();
base[1].c[1][1]=base[1].c[2][1]=base[1].c[2][2]=base[1].c[3][3]=base[1].c[4][4]=1;
base[2].c[1][1]=base[2].c[2][2]=base[2].c[3][2]=base[2].c[3][3]=base[2].c[4][4]=1;
base[3].c[1][1]=base[3].c[1][3]=base[3].c[2][2]=base[3].c[3][3]=base[3].c[4][4]=1;
base[4].c[1][1]=base[4].c[2][2]=base[4].c[3][3]=base[4].c[4][4]=1;
base[5].c[1][1]=base[5].c[3][3]=base[5].c[4][4]=1;
base[6].c[1][1]=base[6].c[2][2]=base[6].c[4][4]=1;
build(1,1,n);
int m(read());
while(m--){
int f(read()),l(read()),r(read());
if(f>=4&&f<=6){
int v=read();
if(f==4)base[4].c[4][1]=v;
else if(f==5)base[5].c[2][2]=v;
else base[6].c[4][3]=v;
}
if(f==7){
ans=query(1,l,r);
printf("%d %d %d\n",ans.c[1][1],ans.c[1][2],ans.c[1][3]);
}
else update(1,l,r,base[f]);
}
return 0;
}
/*
5
0 2 3
3 2 2
2 2 0
1 1 1
2 2 1
4
3 4 5
4 3 4 0
1 1 5
7 3 5
*/