题目: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;
}
View Code

相关文章: