只过 3,4,其余 WA,内存,时间良好。
简述做法:线段树和只维护最上面一行,懒标记维护 4*4.
//LuoFeng Nanami ver.
#include<bits/stdc++.h>
#define ll long long
#define rll register ll
#define F(i, a, b) for(rll i = a; i <= b; i++)
#define Fdn(i, a, b) for(rll i = a; i >= b; i--)
#define int ll
#define pii pair<int, int>
#define fi first
#define se second
#define ld long double
using namespace std;
const int inf = 0x3f3f3f3f3f3f3f3f, mod = 998244353;
const int maxn = 2.5e5 + 7;
int n, m;
struct SMT {
int qjm[4];
}Tree[maxn << 2];
SMT a[maxn];
struct _SMT {
bool fl;
int qjm[4][4];
}Lazy[maxn << 2];
inline void P(SMT &ans, SMT a, SMT b) { F(i, 0, 3) ans.qjm[i] = ((ll)a.qjm[i] + b.qjm[i]) % mod; }
inline void M(SMT &ans, SMT a, _SMT b) { F(i, 0, 3) { ans.qjm[i] = 0; F(j, 0, 3) (ans.qjm[i] += ((ll)a.qjm[j] * b.qjm[j][i]) % mod) %= mod; } }
inline void M(_SMT &ans, _SMT a, _SMT b) { F(i, 0, 3) F(j, 0, 3) { ans.qjm[i][j] = 0; F(k, 0, 3) (ans.qjm[i][j] += ((ll)a.qjm[i][k] * b.qjm[k][j]) % mod) %= mod; } }
inline void Z(SMT &ans, SMT a) { F(i, 0, 3) ans.qjm[i] = a.qjm[i]; }
inline void Z(_SMT &ans, _SMT a) { F(i, 0, 3) F(j, 0, 3) ans.qjm[i][j] = a.qjm[i][j]; }
_SMT _1, _2, _3, _4, _5, _6, I;
inline void Init() {
I.qjm[0][0] = I.qjm[1][1] = I.qjm[2][2] = I.qjm[3][3] = 1;
Z(_1, I); _1.qjm[1][0] = 1;
Z(_2, I); _2.qjm[2][1] = 1;
Z(_3, I); _3.qjm[0][2] = 1;
Z(_4, I); Z(_5, I); Z(_6, I); _6.qjm[2][2] = 0;
}
inline void TEST(SMT &a, SMT b) { b.qjm[1] = 114514; cout << a.qjm[1] << '\n'; }
SMT tst;
inline void DEBUG(SMT a) { cout << "DEBUG\n"; F(i, 0, 2) cout << a.qjm[i] << " "; cout << "DEBUG\n"; }
inline void DEBUG(_SMT a) { cout << "DEBUG\n"; F(i, 0, 3) { F(j, 0, 3) cout << a.qjm[i][j] << " "; cout << '\n'; } cout << "DEBUG\n"; }
inline void PushUp(int p) { P(Tree[p], Tree[p << 1], Tree[p << 1 | 1]); }
inline void PushDown(int p) {
if(Lazy[p].fl) {
M(Tree[p << 1], Tree[p << 1], Lazy[p]);
M(Tree[p << 1 | 1], Tree[p << 1 | 1], Lazy[p]);
M(Lazy[p << 1], Lazy[p << 1], Lazy[p]);
M(Lazy[p << 1 | 1], Lazy[p << 1 | 1], Lazy[p]);
Z(Lazy[p], I);
Lazy[p].fl = 0;
}
}
inline void Build(int p, int l, int r) {
if(l == r) return Z(Tree[p], a[l]), Z(Lazy[p], I), void();
int mid = (l + r) >> 1;
Build(p << 1, l, mid), Build(p << 1 | 1, mid + 1, r);
PushUp(p);
}
inline void Modify(int p, int l, int r, int s, int t, _SMT q) {
if(s <= l && r <= t) return M(Tree[p], Tree[p], q), M(Lazy[p], Lazy[p], q), Lazy[p].fl = 1, void();
int mid = (l + r) >> 1;
PushDown(p);
if(s <= mid) Modify(p << 1, l, mid, s, t, q);
if(mid < t) Modify(p << 1 | 1, mid + 1, r, s, t, q);
PushUp(p);
}
inline SMT Query(int p, int l, int r, int s, int t) {
if(s <= l && r <= t) return Tree[p];
int mid = (l + r) >> 1;
PushDown(p);
SMT ret;
F(i, 0, 3) ret.qjm[i] = 0;
if(s <= mid) P(ret, ret, Query(p << 1, l, mid, s, t));
if(mid < t) P(ret, ret, Query(p << 1 | 1, mid + 1, r, s, t));
return ret;
}
signed main() {
//freopen("glz.in", "r", stdin);
//freopen("glz.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n;
F(i, 1, n) {
int A, B, C; cin >> A >> B >> C;
a[i].qjm[0] = A, a[i].qjm[1] = B, a[i].qjm[2] = C, a[i].qjm[3] = 1;
}
cin >> m;
Init();
Build(1, 1, n);
F(i, 1, m) {
int op, l, r, v; cin >> op >> l >> r;
if(op == 1) {
Modify(1, 1, n, l, r, _1);
} else if(op == 2) {
Modify(1, 1, n, l, r, _2);
} else if(op == 3) {
Modify(1, 1, n, l, r, _3);
} else if(op == 4) {
cin >> v; _4.qjm[3][0] = v;
Modify(1, 1, n, l, r, _4);
} else if(op == 5) {
cin >> v; _5.qjm[1][1] = v;
Modify(1, 1, n, l, r, _5);
} else if(op == 6) {
cin >> v; _6.qjm[3][2] = v;
Modify(1, 1, n, l, r, _6);
} else {
SMT ans = Query(1, 1, n, l, r);
F(i, 0, 2) cout << ans.qjm[i] << " ";
cout << '\n';
}
/*SMT ans = Query(1, 1, n, 1, 2);
F(i, 0, 2) cout << ans.qjm[i] << " ans";
cout << '\n';*/
}
return 0;
}