P7453
我终于过力
线段树维护矩阵区间和的大卡常师
srds感觉这题不卡常
造屎山的过程不尽顺利
但是终究还是造出来了
事实告诉我们,模板常打常新因为后面的那几个20pts都是因为有个pushdown没有打
此题唯一可以说的点就是加入常量1来维护加常数的操作如 \(A_i=A_i+v\)
六个转移矩阵如下:
\[\begin{bmatrix}1&0&0&0\\1&1&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix} \begin{bmatrix}1&0&0&0\\0&1&0&0\\0&1&1&0\\0&0&0&1\end{bmatrix} \begin{bmatrix}1&0&1&0\\0&1&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix} \begin{bmatrix}1&0&0&v\\0&1&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix} \begin{bmatrix}1&0&0&0\\0&v&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix} \begin{bmatrix}1&0&0&0\\0&1&0&0\\0&0&0&v\\0&0&0&1\end{bmatrix}\]维护时使用这六个矩阵区修 \(\begin{bmatrix}A_i&B_i&C_i&1\end{bmatrix}\) 即可
感谢@FreeTimeLove提供hack数据
还是放下代码吧,首个5k码量,值得纪念
// coding by cxz_0
#include <bits/stdc++.h>
#define awa cerr << "xlx is my superman!!!!!!!!!!!\n";
#define FOR(x,l,r) for(int (x) = (l); (x) <= (r); (x)++)
#define _FOR(x,l,r) for(int (x) = (r); (x) >= (l); (x)--)
#define gc getchar()
#define pb emplace_back
#define mp make_pair
#define pii pair<int, int >
#define PII pair<ll, ll >
#define fi first
#define se second
#define p_q priority_queue
// #define int ll
#define il inline
using namespace std;
typedef long long ll;
const int N = 3e5 + 1,MOD = 998244353;
int n, m;
namespace cxz_0
{
il int read(int x=0,bool f=0,char c=gc){while(!isdigit(c))f=c=='-',c=gc;while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=gc;return f?-x:x;}
il void write(int x){if(x<0)x=-x,putchar('-');if(x>9)write(x/10);putchar(x%10+'0');}
il ll readl(ll x=0,bool f=0,char c=gc){while(!isdigit(c))f=c=='-',c=gc;while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=gc;return f?-x:x;}
il void writel(ll x){if(x<0)x=-x,putchar('-');if(x>9)write(x/10);putchar(x%10+'0');}
il int qpow(int a, int n, int p){int b=1;while(n){if(n&1)b=1ll*b*a%p;a=1ll*a*a%p;n>>=1;}return b;}
il int max(int&a,int&b){return a>b?a:b;}
il int min(int&a,int&b){return a<b?a:b;}
il void swap(int&a,int&b){a^=b^=a^=b;}
il int Mod(int x){return x>=MOD?x-MOD:x;}
} using namespace cxz_0;
struct Matrix
{
int M[5][5], _r, _c;
Matrix () {memset (M, 0, sizeof (M));}
il void clear () {memset(M, 0, sizeof (M));}
il void init () {FOR (i, 1, min (_r, _c)) M[i][i] = 1;}
il Matrix operator + (const Matrix& a) const
{
Matrix ret;
ret._r = _r; ret._c = _c;
FOR (i, 1, _r) FOR (j, 1, _c) ret.M[i][j] = Mod (M[i][j] + a.M[i][j]);
return ret;
}
il Matrix operator * (const Matrix& a) const
{
Matrix ret;
ret._r = _r; ret._c = _c;
FOR (i, 1, _r) FOR (j, 1, _c) FOR (k, 1, a._c)
{
ret.M[i][j] += (1ll * M[i][k] * a.M[k][j]) % MOD;
ret.M[i][j] = Mod (ret.M[i][j]);
}
return ret;
}
il void debugMatrix ()
{
FOR (i, 1, _r)
{
FOR (j, 1, _c) cerr << M[i][j] << " ";
cerr << endl;
}
}
il void printMatrix ()
{
FOR (i, 1, _r)
{
FOR (j, 1, _c - 1) printf ("%d ", M[i][j]);
puts("");
}
}
}a[N];
struct Segtr
{
Matrix M_sum, laz;
#define lc (p << 1)
#define rc (p << 1 | 1)
#define MID int mid = (l + r) >> 1
}tr[N << 2];
il void pushup (int p)
{
tr[p].M_sum = tr[lc].M_sum + tr[rc].M_sum;
}
il void pushdown (int p)
{
tr[lc].M_sum = tr[lc].M_sum * tr[p].laz;
tr[rc].M_sum = tr[rc].M_sum * tr[p].laz;
tr[lc].laz = tr[lc].laz * tr[p].laz;
tr[rc].laz = tr[rc].laz * tr[p].laz;
tr[p].laz.clear ();
tr[p].laz.init ();
}
il void build (int p, int l, int r)
{
tr[p].M_sum._r = 1, tr[p].M_sum._c = tr[p].laz._r = tr[p].laz._c = 4;
tr[p].laz.init ();
if (l == r)
{
tr[p].M_sum = a[l];
return;
}
MID;
build (lc, l, mid);
build (rc, mid + 1, r);
pushup (p);
}
il void modify (int p, int l, int r, int ql, int qr, Matrix k)
{
if (ql <= l && r <= qr)
{
tr[p].M_sum = tr[p].M_sum * k;
tr[p].laz = tr[p].laz * k;
return;
}
pushdown (p);
MID;
if (ql <= mid) modify (lc, l, mid, ql, qr, k);
if (qr > mid) modify (rc, mid + 1, r, ql, qr, k);
pushup (p);
}
il Matrix query (int p, int l, int r, int ql, int qr)
{
if (ql <= l && r <= qr) return tr[p].M_sum;
MID;
pushdown (p);
Matrix ret;
ret._r = 1, ret._c = 4;
if (ql <= mid) ret = ret + query(lc, l, mid, ql, qr);
if (qr > mid) ret = ret + query(rc, mid + 1, r, ql, qr);
return ret;
}
Matrix base;
signed main()
{
#ifndef ONLINE_JUDGE
double start = clock();
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
#endif
base._c = base._r = 4;
scanf ("%d", &n);
FOR (i, 1, n)
{
int x, y, z;
scanf ("%d%d%d", &x, &y, &z);
a[i].M[1][1] = x, a[i].M[1][2] = y, a[i].M[1][3] = z, a[i].M[1][4] = 1;
a[i]._r = 1, a[i]._c = 4;
}
build (1, 1, n);
scanf ("%d", &m);
while (m--)
{
int op, l, r, v;
scanf ("%d%d%d", &op, &l, &r);
if (op == 7){query (1, 1, n, l, r).printMatrix ();continue;}
base.clear ();
base.init ();
if (op >= 4 && op <= 6) scanf ("%d", &v);
if (op == 1) base.M[2][1] = 1;
else if (op == 2) base.M[3][2] = 1;
else if (op == 3) base.M[1][3] = 1;
else if (op == 4) base.M[4][1] = v;
else if (op == 5) base.M[2][2] = v;
else if (op == 6) base.M[3][3] = 0, base.M[4][3] = v;
modify (1, 1, n, l, r, base);
}
#ifndef ONLINE_JUDGE
cerr << "Time: " << 1e3 * (clock() - start) / CLOCKS_PER_SEC << " ms" << endl;
awa
#endif
return 0;
}
/*5
0 2 3
3 2 2
2 2 0
1 1 1
2 2 1
4
3 4 5
4 3 4 0
1 1 5
7 3 5*/
从下午到晚上一直在看ddp的相关知识
明天继续
标签:01,Matrix,16,int,ret,il,bmatrix,2023,define From: https://www.cnblogs.com/cxz-stO/p/17056302.html