【线段树维护矩阵向量】LibreOJ - 2980 大魔法师
线段树维护矩阵模板题
#include <bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std;
#define LL long long
#define ll long long
#define ULL unsigned long long
#define Pair pair<LL,LL>
#define ls rt<<1
#define rs rt<<1|1
#define Pi acos(-1.0)
#define eps 1e-6
#define DBINF 1e100
#define mod 998244353
#define MAXN 1e18
#define MS 250009
int n,m;
struct matrix{
LL rown,coln,a[5][5];
}p[MS<<2];
matrix la[MS<<2],I;
bool isla[MS<<2];
matrix operator + (matrix t1,matrix t2){
matrix t = {t1.rown,t1.coln};
memset(t.a,0,sizeof t.a);
for(int i=1;i<=t.rown;i++){
for(int j=1;j<=t.coln;j++){
t.a[i][j] = t1.a[i][j] + t2.a[i][j];
t.a[i][j] %= mod;
}
}
return t;
}
matrix operator * (matrix t1,matrix t2){
matrix t = {t1.rown,t2.coln};
memset(t.a,0,sizeof t.a);
for(int u=1;u<=t.rown;u++){
for(int v=1;v<=t.coln;v++){
for(int i=1;i<=t1.coln;i++){
t.a[u][v] += t1.a[u][i]*t2.a[i][v];
t.a[u][v] %= mod;
}
}
}
return t;
}
void push_up(int rt){
p[rt] = p[ls] + p[rs];
}
void build(int l,int r,int rt){
la[rt] = I;
if(l == r){
LL a,b,c;
cin >> a >> b >> c;
p[rt] = {1,4};
p[rt].a[1][1] = a;
p[rt].a[1][2] = b;
p[rt].a[1][3] = c;
p[rt].a[1][4] = 1;
return;
}
int m = l+r>>1;
build(l,m,ls);
build(m+1,r,rs);
push_up(rt);
}
void update(int rt,matrix f){
p[rt] = p[rt] * f;
la[rt] = la[rt] * f;
isla[rt] = 1;
}
void push_down(int rt){
if(isla[rt]){
update(ls,la[rt]);
update(rs,la[rt]);
la[rt] = I;
isla[rt] = 0;
}
}
void modify(int L,int R,int l,int r,int rt,matrix f){
if(L <= l && r <= R){
update(rt,f);
return;
}
int m = l+r>>1;
push_down(rt);
if(m >= L) modify(L,R,l,m,ls,f);
if(m < R) modify(L,R,m+1,r,rs,f);
push_up(rt);
}
matrix query(int L,int R,int l,int r,int rt){
if(L <= l && r <= R){
return p[rt];
}
int m = l+r>>1;
push_down(rt);
if(m < L) return query(L,R,m+1,r,rs);
else if(m >= R) return query(L,R,l,m,ls);
else return query(L,R,l,m,ls) + query(L,R,m+1,r,rs);
}
void init(){
I = {4,4};
for(int i=1;i<=4;i++) I.a[i][i] = 1;
}
int main() {
ios::sync_with_stdio(false);
cin >> n;
init(); build(1,n,1);
cin >> m;
matrix f = {4,4};
for(int i=1;i<=m;i++){
LL op,l,r,val;
cin >> op >> l >> r;
memset(f.a,0,sizeof f.a);
if(op == 1){
f.a[1][1] = f.a[2][1] = f.a[2][2] = f.a[3][3] = f.a[4][4] = 1;
}
else if(op == 2){
f.a[1][1] = f.a[2][2] = f.a[3][2] = f.a[3][3] = f.a[4][4] = 1;
}
else if(op == 3){
f.a[1][1] = f.a[2][2] = f.a[1][3] = f.a[3][3] = f.a[4][4] = 1;
}
else if(op == 4){
f.a[1][1] = f.a[2][2] = f.a[3][3] = f.a[4][4] = 1;
cin >> f.a[4][1];
}
else if(op == 5){
f.a[1][1] = f.a[3][3] = f.a[4][4] = 1;
cin >> f.a[2][2];
}
else if(op == 6){
f.a[1][1] = f.a[2][2] = f.a[4][4] = 1;
cin >> f.a[4][3];
}
if(op != 7) modify(l,r,1,n,1,f);
else{
matrix ans = query(l,r,1,n,1);
cout << ans.a[1][1] << " ";
cout << ans.a[1][2] << " ";
cout << ans.a[1][3] << "\n";
}
}
return 0;
}

浙公网安备 33010602011771号