rt
这道题太卡常了,有没有人帮我看看哪里可以常数级优化的
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int mod = 998244353;
const int maxn = 260000;
int n,m;
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
template <class T>
inline void read(T &a) {
register char c;while (c = getchar(), (c < '0' || c > '9') && c != '-');register bool f = c == '-';register T x = f ? 0 : c - '0';while (c = getchar(), c >= '0' && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48);}a = f ? -x : x;
}
struct mat{
int c[5][5];
mat(){memset(c,0,sizeof(c));}
inline void unit_init(){
memset(c,0,sizeof(c));
for(int i=1;i<=4;i++)
c[i][i] = 1;
}
inline mat operator*(const mat& M){
mat res;
for(register int i=1;i<=4;i++)
for(register int j=1;j<=4;j++)
for(register int k=1;k<=4;k++){
res.c[i][j] = (res.c[i][j] + 1ll*c[i][k]*M.c[k][j]) % mod;
// res.c[i][j] -= (res.c[i][j] >= mod) ? mod : 0;
}
return res;
}
inline mat operator+(const mat &M){
mat res;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
res.c[i][j] = (M.c[i][j] + c[i][j]) % mod;
return res;
}
};
mat Mat[maxn<<2];
mat lazy[maxn<<2];
mat ans;
mat unit;
mat ex_unit;
inline void init_1(){
unit.c[2][1] = 1;
}
inline void init_2(){
unit.c[3][2] = 1;
}
inline void init_3(){
unit.c[1][3] = 1;
}
inline void init_4(int v){
unit.c[4][1] = v;
}
inline void init_5(int v){
unit.c[2][2] = v;
}
inline void init_6(int v){
unit.c[3][3] = 0;
unit.c[4][3] = v;
}
void pushdown(int p){
lazy[ls(p)] = lazy[ls(p)] * lazy[p];
lazy[rs(p)] = lazy[rs(p)] * lazy[p];
Mat[ls(p)] = Mat[ls(p)] * lazy[p];
Mat[rs(p)] = Mat[rs(p)] * lazy[p];
lazy[p].unit_init();
}
inline void pushup(int p){
for(int i=1;i<=4;i++){
Mat[p].c[1][i] = 1ll*(Mat[ls(p)].c[1][i] + Mat[rs(p)].c[1][i]);
Mat[p].c[1][i] -= (Mat[p].c[1][i] >= mod) ? mod : 0;
}
}
void built(int l,int r,int p){
lazy[p] = ex_unit;
if(l == r){
read(Mat[p].c[1][1]);read(Mat[p].c[1][2]);read(Mat[p].c[1][3]);
// scanf("%d %d %d",&Mat[p].c[1][1],&Mat[p].c[1][2],&Mat[p].c[1][3]);
Mat[p].c[1][4] = 1;
return;
}
int mid = (l+r)/2;
built(l,mid,ls(p));
built(mid+1,r,rs(p));
pushup(p);
}
void update(int l,int r,int s,int t,int p,mat M){
if(l >= s && r <= t){
Mat[p] = Mat[p] * M;
lazy[p] = lazy[p] * M;
return;
}
pushdown(p);
int mid = (r+l)>>1;
if(mid >= s)
update(l,mid,s,t,ls(p),M);
if(t > mid)
update(mid+1,r,s,t,rs(p),M);
pushup(p);
}
void query(int l,int r,int s,int t,int p){
if(l >= s && r <= t){
for(register int i=1;i<=3;i++){
ans.c[1][i] = ans.c[1][i]+Mat[p].c[1][i];
ans.c[1][i] -= (ans.c[1][i] >= mod) ? mod : 0;
}
return;
}
int mid = (l+r)>>1;
pushdown(p);
if(mid >= s)
query(l,mid,s,t,ls(p));
if(t > mid)
query(mid+1,r,s,t,rs(p));
}
signed main()
{
ex_unit.unit_init();
read(n);
built(1,n,1);
read(m);
for(int i=1;i<=m;i++){
unit = ex_unit;
int opt,l,r,v;
read(opt);read(l);read(r);
if(opt == 1){
init_1();
update(1,n,l,r,1,unit);
}
else if(opt == 2){
// init_2();
unit.c[3][2] = 1;
update(1,n,l,r,1,unit);
}
else if(opt == 3){
init_3();
update(1,n,l,r,1,unit);
}
else if(opt == 4){
read(v);
init_4(v);
update(1,n,l,r,1,unit);
}
else if(opt == 5){
read(v);
init_5(v);
update(1,n,l,r,1,unit);
}
else if(opt == 6){
read(v);
init_6(v);
update(1,n,l,r,1,unit);
}
else if(opt == 7){
memset(ans.c,0,sizeof(ans.c));
query(1,n,l,r,1);
printf("%d %d %d\n",ans.c[1][1],ans.c[1][2],ans.c[1][3]);
}
}
return 0;
}