rt,求调qwq 测评
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
const int mod = 998244353;
int n, a, b, c, m;
inline int add(int x) {return x > mod ? x - mod : x;}
struct Matrix
{
int c[7][7];
void clear()
{
memset(c, 0, sizeof c);
}
void init()
{
for(int i = 1;i <= 4;i++)
{
c[i][i] = 1;
}
}
Matrix operator * (const Matrix &o) const
{
Matrix ans;
for(int i = 1;i <= 4;i++)
{
for(int j = 1;j <= 4;j++)
{
ans.c[i][j] = add(ans.c[i][j] + (1ll * c[i][1] * o.c[1][j]) % mod);
ans.c[i][j] = add(ans.c[i][j] + (1ll * c[i][2] * o.c[2][j]) % mod);
ans.c[i][j] = add(ans.c[i][j] + (1ll * c[i][3] * o.c[3][j]) % mod);
ans.c[i][j] = add(ans.c[i][j] + (1ll * c[i][4] * o.c[4][j]) % mod);
}
}
return ans;
}
Matrix operator + (const Matrix &o) const
{
Matrix ans;
for(int i = 1;i <= 4;i++)
{
for(int j = 1;j <= 4;j++)
{
ans.c[i][j] = (c[i][j] + o.c[i][j]) % mod;
}
}
return ans;
}
};
Matrix s[N];
struct SegmentTree
{
Matrix c[N << 2], tag[N << 2];
void pushup(int u)
{
c[u] = c[2 * u] + c[2 * u + 1];
}
void pushdown(int u)
{
int ls = 2 * u;
int rs = 2 * u + 1;
c[ls] = c[ls] * tag[u];
c[rs] = c[rs] * tag[u];
tag[ls] = tag[ls] * tag[u];
tag[rs] = tag[rs] * tag[u];
tag[u].clear(), tag[u].init();
}
void build(int u, int l, int r)
{
tag[u].init();
if(l == r)
{
c[u] = s[l];
return;
}
int mid = (l + r) >> 1;
build(2 * u, l, mid);
build(2 * u + 1, mid + 1, r);
pushup(u);
}
void update(int u, int l, int r, int L, int R, Matrix v)
{
if(L <= l && r <= R)
{
c[u] = c[u] * v;
tag[u] = tag[u] * v;
return;
}
pushdown(u);
int mid = (l + r) >> 1;
if(R > mid)
{
update(2 * u + 1, mid + 1, r, L, R, v);
}
if(L <= mid)
{
update(2 * u, l, mid, L, R, v);
}
pushup(u);
}
Matrix query(int u, int l, int r, int L, int R)
{
if(L <= l && r <= R)
{
return c[u];
}
pushdown(u);
Matrix ans;
ans.clear();
int mid = (l + r) >> 1;
if(L <= mid)
{
ans = ans + query(2 * u, l, mid, L, R);
}
if(R > mid)
{
ans = ans + query(2 * u + 1, mid + 1, r, L, R);
}
return ans;
}
}sg;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for(int i = 1;i <= n;i++)
{
cin >> s[i].c[1][1];
cin >> s[i].c[1][2];
cin >> s[i].c[1][3];
s[i].c[1][4] = 1;
}//行向量, 向量乘矩阵
cin >> m;
int opt;
int l, r, v;
sg.build(1, 1, n);
for(int i = 1;i <= m;i++)
{
Matrix tmp;
tmp.clear();
tmp.init();
cin >> opt;
cin >> l >> r;
if(opt == 1)
{
tmp.c[2][1] = 1;
sg.update(1, 1, n, l, r, tmp);
}
if(opt == 2)
{
tmp.c[3][2] = 1;
sg.update(1, 1, n, l, r, tmp);
}
if(opt == 3)
{
tmp.c[1][3] = 1;
sg.update(1, 1, n, l, r, tmp);
}
if(opt == 4)
{
cin >> v;
tmp.c[4][1] = v;
sg.update(1, 1, n, l, r, tmp);
}
if(opt == 5)
{
cin >> v;
tmp.c[2][2] = v;
sg.update(1, 1, n, l, r, tmp);
}
if(opt == 6)
{
cin >> v;
tmp.c[3][3] = 0;
tmp.c[4][3] = v;
sg.update(1, 1, n, l, r, tmp);
}
if(opt == 7)
{
Matrix q = sg.query(1, 1, n, l, r);
cout << q.c[1][1] << " " << q.c[1][2] << " " << q.c[1][3] << endl;
}
}
return 0;
}