题目:https://loj.ac/problem/2980
线段树维护矩阵。
然后是 30 分。似乎是被卡常了?……
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define ls Ls[cr] #define rs Rs[cr] using namespace std; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return fx?ret:-ret; } const int N=2e5+5e4+5,M=5e5+5,mod=998244353; int upt(int x){while(x>=mod)x-=mod;while(x<0)x+=mod;return x;} int n,m,a[N],b[N],c[N],tot,Ls[M],Rs[M]; struct Mtr{ int a[4][4]; Mtr(){memset(a,0,sizeof a);} void init(){for(int i=0;i<4;i++)a[i][i]=1;} Mtr operator* (const Mtr &b)const { Mtr c; for(int i=0;i<4;i++) for(int k=0;k<4;k++) for(int j=0;j<4;j++) c.a[i][j]=(c.a[i][j]+(ll)a[i][k]*b.a[k][j])%mod; return c; } Mtr operator+ (const Mtr &b)const { Mtr c=*this; for(int i=0;i<3;i++)c.a[0][i]=upt(c.a[0][i]+b.a[0][i]); return c; } bool operator== (const Mtr &b)const { for(int i=0;i<4;i++) for(int j=0;j<4;j++)if(a[i][j]!=b.a[i][j])return false; return true; } }Ml[5],vl[M],tg[M],I,tp; void build(int l,int r,int cr) { if(l==r) { vl[cr].a[0][0]=a[l]; vl[cr].a[0][1]=b[l]; vl[cr].a[0][2]=c[l]; vl[cr].a[0][3]=1; return; } int mid=l+r>>1; tg[cr].init(); ls=++tot; build(l,mid,ls); rs=++tot; build(mid+1,r,rs); vl[cr]=vl[ls]+vl[rs]; vl[cr].a[0][3]=r-l+1; } void init() { tot=1; build(1,n,1); for(int i=1;i<=3;i++)Ml[i].init(); Ml[1].a[1][0]=1; Ml[2].a[2][1]=1; Ml[3].a[0][2]=1; I.init(); } void pshd(int cr) { if(tg[cr]==I)return; tg[ls]=tg[ls]*tg[cr]; tg[rs]=tg[rs]*tg[cr]; vl[ls]=vl[ls]*tg[cr]; vl[rs]=vl[rs]*tg[cr]; tg[cr]=I; } void mdfy(int l,int r,int cr,int L,int R,int op,int v) { if(l>=L&&r<=R) { if(op<=3)tp=Ml[op]; if(op==4){ tp=I; tp.a[3][0]=v;} if(op==5){ tp=I; tp.a[1][1]=v;} if(op==6){ tp=I; tp.a[2][2]=0; tp.a[3][2]=v;} tg[cr]=tg[cr]*tp; vl[cr]=vl[cr]*tp; return; } int mid=l+r>>1; pshd(cr); if(L<=mid)mdfy(l,mid,ls,L,R,op,v); if(mid<R)mdfy(mid+1,r,rs,L,R,op,v); vl[cr]=vl[ls]+vl[rs]; vl[cr].a[0][3]=r-l+1; } Mtr qry(int l,int r,int cr,int L,int R) { if(l>=L&&r<=R)return vl[cr]; int mid=l+r>>1; pshd(cr); if(L>mid)return qry(mid+1,r,rs,L,R); if(R<=mid)return qry(l,mid,ls,L,R); return qry(l,mid,ls,L,R)+qry(mid+1,r,rs,L,R); } int main() { n=rdn(); for(int i=1;i<=n;i++)a[i]=rdn(),b[i]=rdn(),c[i]=rdn(); init(); m=rdn(); int op,l,r,v=0; while(m--) { op=rdn();l=rdn();r=rdn(); if(op==7) { Mtr ans=qry(1,n,1,l,r); printf("%d %d %d\n",ans.a[0][0],ans.a[0][1],ans.a[0][2]); } if(op>=4&&op<=6)v=rdn(); if(op<7)mdfy(1,n,1,l,r,op,v); } return 0; }