题目


分析

首先考虑如果修改操作都是单点修改怎么做,

以第一种修改为例那么就是

\[\left[\begin{matrix}A\\B\\C\\1\end{matrix}\right] \times \left[\begin{matrix}1,0,0,0\\1,1,0,0\\0,0,1,0\\0,0,0,1\end{matrix}\right]=\left[\begin{matrix}A+B\\B\\C\\1\end{matrix}\right]
\]

同理其它操作也能通过乘矩阵来维护,

考虑区间修改时询问为求和,那么只需要开懒标记即可

时间复杂度 \(O(4^3Q\log_2{n})\)


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=250011,mod=998244353;
typedef long long lll; int n;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct maix{
lll p[4][4];
inline maix operator *(const maix &t)const{
rr maix _t;
for (rr int i=0;i<4;++i)
for (rr int j=0;j<4;++j){
_t.p[i][j]=0;
for (rr int k=0;k<4;++k)
_t.p[i][j]+=p[i][k]*t.p[k][j];
_t.p[i][j]%=mod;
}
return _t;
}
}u,lazy[N<<2];
struct Four{
lll p[4];
inline Four operator +(const Four &t)const{
rr Four _t;
for (rr int i=0;i<4;++i)
_t.p[i]=p[i]+t.p[i]>=mod?p[i]+t.p[i]-mod:p[i]+t.p[i];
return _t;
}
}ANS,w[N<<2];
inline bool Is_Unit(maix A){
for (rr int i=0;i<4;++i)
for (rr int j=0;j<4;++j)
if (A.p[i][j]!=u.p[i][j]) return 0;
return 1;
}
inline Four mul(Four A,maix B){
rr Four C;
for (rr int i=0;i<4;++i){
C.p[i]=0;
for (rr int j=0;j<4;++j)
C.p[i]+=A.p[j]*B.p[j][i];
C.p[i]%=mod;
}
return C;
}
inline void pdown(int k){
w[k<<1]=mul(w[k<<1],lazy[k]);
lazy[k<<1]=lazy[k<<1]*lazy[k];
w[k<<1|1]=mul(w[k<<1|1],lazy[k]);
lazy[k<<1|1]=lazy[k<<1|1]*lazy[k];
lazy[k]=u;
}
inline void build(int k,int l,int r){
lazy[k]=u;
if (l==r){
for (rr int i=0;i<3;++i)
w[k].p[i]=iut();
w[k].p[3]=1;
return;
}
rr int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
w[k]=w[k<<1]+w[k<<1|1];
}
inline void update(int k,int l,int r,int x,int y,maix z){
if (l==x&&r==y) {w[k]=mul(w[k],z),lazy[k]=lazy[k]*z; return;}
rr int mid=(l+r)>>1; if (!Is_Unit(lazy[k])) pdown(k);
if (y<=mid) update(k<<1,l,mid,x,y,z);
else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
else update(k<<1,l,mid,x,mid,z),update(k<<1|1,mid+1,r,mid+1,y,z);
w[k]=w[k<<1]+w[k<<1|1];
}
inline Four query(int k,int l,int r,int x,int y){
if (l==x&&r==y) return w[k];
rr int mid=(l+r)>>1; if (!Is_Unit(lazy[k])) pdown(k);
if (y<=mid) return query(k<<1,l,mid,x,y);
else if (x>mid) return query(k<<1|1,mid+1,r,x,y);
else return query(k<<1,l,mid,x,mid)+query(k<<1|1,mid+1,r,mid+1,y);
}
signed main(){
for (rr int i=0;i<4;++i) u.p[i][i]=1;
n=iut(),build(1,1,n);
for (rr int Q=iut();Q;--Q){
rr int opt=iut(),l=iut(),r=iut(),w=0; rr maix z=u;
if (opt<7){
if (opt>3) w=iut();
switch (opt){
case 1:{
z.p[1][0]=1;
break;
}
case 2:{
z.p[2][1]=1;
break;
}
case 3:{
z.p[0][2]=1;
break;
}
case 4:{
z.p[3][0]=w;
break;
}
case 5:{
z.p[1][1]=w;
break;
}
case 6:{
z.p[2][2]=0,z.p[3][2]=w;
break;
}
}
update(1,1,n,l,r,z);
}
else{
ANS=query(1,1,n,l,r);
for (rr int i=0;i<3;++i)
print(ANS.p[i]),putchar(i==2?10:32);
}
}
return 0;
}

#线段树,矩阵乘法#洛谷 7453 [THUSCH2017] 大魔法师的更多相关文章

  1. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

  2. hdu 5068(线段树+矩阵乘法)

    矩阵乘法来进行所有路径的运算, 线段树来查询修改. 关键还是矩阵乘法的结合律. Harry And Math Teacher Time Limit: 5000/3000 MS (Java/Others ...

  3. 【对不同形式矩阵的总结】WC 2009 最短路径问题(线段树+矩阵乘法)

    题意 ​ 题目链接:https://www.luogu.org/problem/P4150 ​ 一个 \(6\times n\) 的网格图,每个格点有一个初始权值.有两种操作: 修改一个格子的权值 求 ...

  4. MAZE(2019年牛客多校第二场E题+线段树+矩阵乘法)

    题目链接 传送门 题意 在一张\(n\times m\)的矩阵里面,你每次可以往左右和下三个方向移动(不能回到上一次所在的格子),\(1\)表示这个位置是墙,\(0\)为空地. 现在有\(q\)次操作 ...

  5. CF718C Sasha and Array 线段树 + 矩阵乘法

    有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$   直接求不好求,改成矩阵乘法的形式:  $a_{i}=M^x\times ...

  6. Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门  Portal  原题目描述在最下面.  简单的 ...

  7. LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)

    线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵. #include<iostream> #include<cstdio> #include<cma ...

  8. HDU 5068 Harry And Math Teacher 线段树+矩阵乘法

    题意: 一栋楼有n层,每一层有2个门,每层的两个门和下一层之间的两个门之间各有一条路(共4条). 有两种操作: 0 x y : 输出第x层到第y层的路径数量. 1 x y z : 改变第x层 的 y门 ...

  9. [tsA1490][2013中国国家集训队第二次作业]osu![概率dp+线段树+矩阵乘法]

    这样的题解只能舔题解了,,,qaq 清橙资料里有.. #include <iostream> #include <cstdio> #include <cstdlib> ...

  10. SP1716 GSS3(线段树+矩阵乘法)

    Code: #include <bits/stdc++.h> #define N 50001 #define ll long long #define lson now<<1 ...

随机推荐

  1. Taurus.MVC WebMVC 入门开发教程2:一个简单的页面呈现

    前言: 在上一篇中,我们了解了如何下载.配置和运行 Taurus.MVC WebMVC 框架. 现在,让我们开始编写一个简单的页面并进行呈现. 步骤1:创建控制器 首先,我们需要创建一个控制器来处理页 ...

  2. MYSQL查询数据表中某个字段包含某个数值

    当某个字段中字符串是"1,2,3,4,5,6"或者"123456"查询数据表中某个字段是否包含某个值1:模糊查询  使用like       select * ...

  3. 面向开发者的 ChatGPT 提示工程课程|吴恩达携手OpenAI 教你如何编写 prompt

    提示工程(Prompt Engineering)是一门相对较新的学科,旨在开发和优化提示,从而高效地将语言模型(LM)用于各种应用和研究主题,并帮助开发人员更好地理解大型语言模型(LLM)的能力和局限 ...

  4. ZYNQ核心板及其底板开源啦!

    Hello-FPGA ZYNQ 设计开源啦! 开源ZYNQ核心板 + 底板 硬件设计.软件设计,软件设计使用裸机演示,演示了如何使用AXI DMA等关键dma 模块 欢迎加QQ 讨论 94755958 ...

  5. jquery实现轮播图切换

    这个是我模仿网易云的音乐界面写的轮播图,主要实现的功能有 1.每隔4秒图片和对应的背景颜色一起切换 2.点击翻页会跳转到相对应的图片以及背景上 3.点击左右翻页,实现顺序切换 <1>HTM ...

  6. [Rust] Workspace,Package, Crate 和 Module

    package(包) 一个 package 对应一个项目,package 的信息在 Cargo.toml 里面定义. crate(木箱.箱子) crate 指的是 package 编译后的输出文件.以 ...

  7. 【Azure 应用服务】当在Azure App Service的门户上 Log Stream 日志无输出,需要如何操作让其输出Application Logs呢?

    问题描述 在Azure App Service的门户上 Log Stream 日志无输出,需要如何操作让其输出Application Logs呢? 如下图所示: 问题解答 请注意,上图中提示说:App ...

  8. 【Azure 应用服务】App Service For Linux 环境中,如何修改 Nginx 配置中 server_name的默认值 example.com

    问题描述 在App Service for Linux环境中,部署PHP应用,使用Nginx服务器.因为PHP应用中所有静态资源的URL使用的默认域名为 https://example.com:808 ...

  9. 【Azure API 管理】APIM不能连接到 App Service (APIM cannot connect to APP service)

    问题描述 APIM 无法正确连接到App Service,返回500错误: { "statusCode": 500, "message": "Inte ...

  10. 因IPv4和IPv6协议不同而引发的第三方接口调用失效的问题

    记录一次因IPv4和IPv6协议不同而引发的第三方接口调用失效的问题,仅供大家参考!!! 背景介绍 公司有一个微信小程序,我做后端的,负责给小程序提供数据接口.后来因为一系列原因小程序要对接一个中控( ...