2023年01月16日训练日志

P7453

我终于过力

线段树维护矩阵区间和的大卡常师

srds感觉这题不卡常

造屎山的过程不尽顺利

但是终究还是造出来了

事实告诉我们,模板常打常新因为后面的那几个20pts都是因为有个pushdown没有打

此题唯一可以说的点就是加入常量1来维护加常数的操作如 Ai=Ai+v

六个转移矩阵如下:

[1000110000100001][1000010001100001][1010010000100001][100v010000100001][10000v0000100001][10000100000v0001]

维护时使用这六个矩阵区修 [AiBiCi1] 即可

感谢@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的相关知识

明天继续

posted @   你的洛  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示