PS:如果读过题了可以跳过题目描述直接到题解部分
提交链接:洛谷 P7453 [THUSCH2017] 大魔法师

题目

题目描述

大魔法师小 L 制作了 n n n 个魔力水晶球,每个水晶球有水、火、土三个属性的能量值。小 L 把这 n n n 个水晶球在地上从前向后排成一行,然后开始今天的魔法表演。

我们用 A i , B i , C i A_i,B_i,C_i Ai​,Bi​,Ci​ 分别表示从前向后第 i i i 个水晶球(下标从 1 1 1 开始)的水、火、土的能量值。

小 L 计划施展 m m m 次魔法。每次,他会选择一个区间 [ l , r ] [l,r] [l,r],然后施展以下 3 3 3 大类、 7 7 7 种魔法之一:

  1. 魔力激发:令区间里每个水晶球中特定属性的能量爆发,从而使另一个特定属性的能量增强。具体来说,有以下三种可能的表现形式:

    • 火元素激发水元素能量:令 A i = A i + B i A_i=A_i+B_i Ai​=Ai​+Bi​。
    • 土元素激发火元素能量:令 B i = B i + C i B_i=B_i+C_i Bi​=Bi​+Ci​。
    • 水元素激发土元素能量:令 C i = C i + A i C_i=C_i+A_i Ci​=Ci​+Ai​。

    需要注意的是,增强一种属性的能量并不会改变另一种属性的能量,例如 A i = A i + B i A_i=A_i+B_i Ai​=Ai​+Bi​ 并不会使 B i B_i Bi​ 增加或减少。

  2. 魔力增强:小 L 挥舞法杖,消耗自身 v v v 点法力值,来改变区间里每个水晶球的特定属性的能量。具体来说,有以下三种可能的表现形式:

    • 火元素能量定值增强:令 A i = A i + v A_i=A_i+v Ai​=Ai​+v。
    • 水元素能量翻倍增强:令 B i = B i × v B_i=B_i\times v Bi​=Bi​×v。
    • 土元素能量吸收融合:令 C i = v C_i=v Ci​=v。
  3. 魔力释放:小L将区间里所有水晶球的能量聚集在一起,融合成一个新的水晶球,然后送给场外观众。生成的水晶球每种属性的能量值等于区间内所有水晶球对应能量值的代数和。需要注意的是,魔力释放的过程不会真正改变区间内水晶球的能量。

值得一提的是,小 L 制造和融合的水晶球的原材料都是定制版的 OI 工厂水晶,所以这些水晶球有一个能量阈值 998244353 998244353 998244353。当水晶球中某种属性的能量值大于等于这个阈值时,能量值会自动对阈值取模,从而避免水晶球爆炸。

小 W 为小 L(唯一的)观众,围观了整个表演,并且收到了小 L 在表演中融合的每个水晶球。小 W 想知道,这些水晶球蕴涵的三种属性的能量值分别是多少。

输入格式

从标准输入读入数据。

我们将上述的 7 7 7 种魔法,从上到下依次标号为 1 1 1 ~ 7 7 7。

输入的第一行包含一个整数 n n n( 1 ≤ n ≤ 2.5 × 1 0 5 1\le n\le 2.5\times 10^5 1≤n≤2.5×105),表示水晶球个数。

接下来 n n n 行,每行空格隔开的 3 3 3 个整数,其中第 i i i 行的三个数依次表示 A i , B i , C i A_i,B_i,C_i Ai​,Bi​,Ci​。

接下来一行包含一个整数 m m m( 1 ≤ m ≤ 2.5 × 1 0 5 1\le m\le2.5\times 10^5 1≤m≤2.5×105),表示施展魔法的次数。

接下来 m m m 行,每行 3 3 3 或 4 4 4 个数,格式为 opt l r (v)。其中 opt 表示魔法的编号, l , r l,r l,r 表示施展魔法的区间(保证有 l ≤ r l\le r l≤r)。特别地,如果施展 4 4 4 ~ 6 6 6 号魔法(魔力增强),则还有一个整数 v v v,表示小 L 消耗的法力值。

输出格式

输出到标准输出。

对每个 7 7 7 号魔法(魔力释放),输出一行、空格隔开的 3 3 3 个整数 a b c,分别表示此次融合得到的水晶球的水、火、土元素能量值。

样例 #1

样例输入 #1

2
2 3 3
6 6 6
4
7 1 2
1 1 2
4 1 2 3
7 1 2

样例输出 #1

8 9 9
23 9 9

提示

100 % 100\% 100% 的数据, n , m ≤ 2.5 × 1 0 5 , 0 ≤ A i , B i , C i , v < 998244353 n,m\le2.5\times 10^5,0\le A_i,B_i,C_i,v<998244353 n,m≤2.5×105,0≤Ai​,Bi​,Ci​,v<998244353

  1. 10 % 10\% 10% 的数据, n × m ≤ 1 0 7 n\times m\le10^7 n×m≤107。
  2. 另外 10 % 10\% 10% 的数据,每次魔法的区间均为 [ 1 , n ] [1,n] [1,n]。
  3. 另外 10 % 10\% 10% 的数据,每次非询问魔法的影响区间均为 [ 1 , n ] [1,n] [1,n],所有修改在询问之前。
  4. 另外 10 % 10\% 10% 的数据, opt ⁡ ∈ { 4 , 5 , 6 , 7 } \operatorname{opt}\in\{4,5,6,7\} opt∈{4,5,6,7}。
  5. 另外 15 % 15\% 15% 的数据, opt ⁡ ∈ { 1 , 2 , 7 } \operatorname{opt}\in\{1,2,7\} opt∈{1,2,7}。
  6. 另外 15 % 15\% 15% 的数据, opt ⁡ ∈ { 1 , 2 , 3 , 5 , 7 } \operatorname{opt}\in\{1,2,3,5,7\} opt∈{1,2,3,5,7}。
  7. 另外 15 % 15\% 15% 的数据, n , m ≤ 1 0 5 n,m\le 10^5 n,m≤105。
  8. 其他数据,无特殊约定。

样例解释

以下展示每次施展魔法后,两个水晶球内的能量:

(2, 3, 3) (6, 6, 6)
(5, 3, 3) (12, 6, 6)
(8, 3, 3) (15, 6, 6)
(8, 3, 3) (15, 6, 6)

题解

如同标签所述,这道题就三个考点,我们一个一个讲。

  1. 矩阵(自己到我之前的博客里面看吧)
    ☝这个是链接
    这道题主要是要把矩阵定义成一个单独的结构体,线段树里要用。前六个不同的操作也都要单独赋值成一个矩阵。
    4*4的矩阵主要表示每一个节点的A,B,C,Len。
  • 操作1

  • 操作2

  • 操作3

  • 操作4

  • 操作5

  • 操作6
    要注意矩阵相乘的顺序!!!

  1. 线段树
    线段树的每一个节点元素都是一个矩阵,包括他们的val和tag在内。(下面空着的就不要了)
  • val

  • tag(记得赋初值!!!)

  1. 常数优化
  • 把矩阵乘法最里面一层展开
  • 使用快读快写
  • 减少取模的次数,用强制转换解决爆int的问题

代码实现

//洛谷 P7453 [THUSCH2017] 大魔法师
#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mo=998244353;
int n;
int m;
int opt;
int l,r,v;
int totr;struct mat{int num[4][4];mat(){memset(num,0,sizeof(num));}mat operator + (const mat x)const{mat a;for(int i=0;i<4;++i){for(int j=0;j<4;++j){a.num[i][j]=(1ll*num[i][j]+1ll*x.num[i][j])%mo;}}return a;}mat operator * (const mat x)const{mat a;for(int i=0;i<4;++i){for(int j=0;j<4;++j){a.num[i][j]=(1ll*a.num[i][j]+1ll*num[0][j]*x.num[i][0])%mo;a.num[i][j]=(1ll*a.num[i][j]+1ll*num[1][j]*x.num[i][1])%mo;a.num[i][j]=(1ll*a.num[i][j]+1ll*num[2][j]*x.num[i][2])%mo;a.num[i][j]=(1ll*a.num[i][j]+1ll*num[3][j]*x.num[i][3])%mo;}}return a;}}a[250010],o[8],ans;struct Node{mat val;mat tag;//延迟下放值Node(){tag.num[0][0]=tag.num[1][1]=tag.num[2][2]=tag.num[3][3]=1;}}rt[1000100];void in(int &x){int nt;x=0;while(!isdigit(nt=getchar()));x=nt^'0';while(isdigit(nt=getchar())){x=(x<<3)+(x<<1)+(nt^'0');}
}inline mat calc(int x){//当前区间之和 return rt[x].tag*rt[x].val;
}inline void push_down(int x){//tag延迟下放 rt[x<<1].tag=rt[x].tag*rt[x<<1].tag;//左子节点的tag加父节点的tag rt[x<<1|1].tag=rt[x].tag*rt[x<<1|1].tag;//右子节点的tag加父节点的tagrt[x].tag=mat();//父节点的tag清除 rt[x].tag.num[0][0]=rt[x].tag.num[1][1]=rt[x].tag.num[2][2]=rt[x].tag.num[3][3]=1;
}inline int build(int x,int l,int r){//建树if(l==r){//找到最下面的单个点 rt[x].val=a[r];return x;}int mid=(l+r)/2;build(x<<1,l,mid);//建左树build(x<<1|1,mid+1,r);//建右树rt[x].val=rt[x<<1].val+rt[x<<1|1].val;//本节点的左右子节点之和return x;
}inline void update(int x,int L,int R,int l,int r,mat v){//l~r区间值加vif(l<=L&&R<=r){rt[x].tag=v*rt[x].tag;return ;}int mid=(L+R)/2;push_down(x);if(l<=mid){update(x<<1,L,mid,l,r,v);}if(r>mid){update(x<<1|1,mid+1,R,l,r,v);}rt[x].val=calc(x<<1)+calc(x<<1|1);//左右子节点之和
}inline mat query(int x,int L,int R,int l,int r){if(l<=L&&r>=R){return calc(x);}int mid=(L+R)>>1;mat tmp;push_down(x);rt[x].val=calc(x<<1)+calc(x<<1|1);if(l<=mid){tmp=tmp+query(x<<1,L,mid,l,r);}if(r>mid){tmp=tmp+query(x<<1|1,mid+1,R,l,r);}return tmp;
}int main(){register int i;in(n);for(i=1;i<=n;++i){in(a[i].num[0][0]),in(a[i].num[0][1]),in(a[i].num[0][2]);a[i].num[0][3]=1;}build(1,1,n);o[1].num[0][0]=o[1].num[1][0]=o[1].num[1][1]=o[1].num[2][2]=o[1].num[3][3]=1;o[2].num[0][0]=o[2].num[1][1]=o[2].num[2][1]=o[2].num[2][2]=o[2].num[3][3]=1;o[3].num[0][0]=o[3].num[1][1]=o[3].num[2][2]=o[3].num[0][2]=o[3].num[3][3]=1;o[4].num[0][0]=o[4].num[1][1]=o[4].num[2][2]=o[4].num[3][3]=1;o[5].num[0][0]=o[5].num[2][2]=o[5].num[3][3]=1;o[6].num[0][0]=o[6].num[1][1]=o[6].num[3][3]=1;in(m);for(i=1;i<=m;++i){in(opt);in(l),in(r);if(opt>=4&&opt<=6){in(v);v%=mo;if(opt==4){o[4].num[3][0]=v;update(1,1,n,l,r,o[4]);}else if(opt==5){o[5].num[1][1]=v;update(1,1,n,l,r,o[5]);}else{o[6].num[3][2]=v;update(1,1,n,l,r,o[6]);}}else{if(opt<=3){update(1,1,n,l,r,o[opt]);}else{ans=query(1,1,n,l,r);printf("%d %d %d\n",ans.num[0][0],ans.num[0][1],ans.num[0][2]);}}}return 0;
}

洛谷 P7453 [THUSCH2017] 大魔法师相关推荐

  1. P7453 [THUSCH2017] 大魔法师 题解

    题目链接 感觉本题没有太多思维难度,纯DS 大致思路把每个位置的三个属性看做一个 1 × 4 1\times 4 1×4 的矩阵(第四个位置维护常数项),并用线段树维护区间矩阵和 同时,我们计算出六种 ...

  2. 洛谷 P1230 智力大冲浪

    我的第一篇题解(辣鸡题解)洛谷 P1230 智力大冲浪 题目描述 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元.先不要太高兴!因为 ...

  3. 洛谷 P2867 [USACO06NOV]大广场Big Square

    P2867 [USACO06NOV]大广场Big Square 题目描述 Farmer John's cows have entered into a competition with Farmer ...

  4. AC日记——神奇的幻方 洛谷 P2615(大模拟)

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,--,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  5. 洛谷P1230 智力大冲浪(贪心)

    P1230 智力大冲浪 题解:准着一个贪心思想,在尽可能短的时间内,做价值尽可能多的题. 因此,我们可以按照价值从大到小排个序,然后对于每一道题看在时间限制内可以做哪几道题.时间复杂度Θ(N2)\Th ...

  6. 洛谷P1230 智力大冲浪

    题目描述 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者 m 元.先不要太高兴,因为这些钱还不一定都是你的.接下来主持人宣布了比赛规则: ...

  7. 做题记录 洛谷P1230 智力大冲浪

    题目描述 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元.先不要太高兴!因为这些钱还不一定都是你的?!接下来主持人宣布了比赛规则: ...

  8. 洛谷p1230 智力大冲浪 (贪心问题)

    题目描述 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元.先不要太高兴!因为这些钱还不一定都是你的?!接下来主持人宣布了比赛规则: ...

  9. [洛谷P5340][TJOI2019]大中锋的游乐场

    题目大意:有$n(n\leqslant10^4)$个点,$m(m\leqslant10^5)$条边的无向图,每个点有一个属性$A/B$,要求$|cnt_A-cnt_B|\leqslant k(k\le ...

最新文章

  1. Compression Helper Class using SharpZipLib
  2. redis缓存失效时间设为多少_java操作Redis缓存设置过期时间的方法
  3. python爬虫完整实例-python爬虫实战之爬取京东商城实例教程
  4. 《时间管理:如何充分利用你的24小时》—让你时间发挥最大效用
  5. Streaming的算法Reservoir Sampling
  6. python 定义数组
  7. 三维视觉前沿进展年度报告
  8. 02_Storm集群部署
  9. Android初始化语言 (init.*.rc、init.conf文件格式)
  10. 漫画:图的最短路径问题
  11. e5服务器系列天梯图,至强e5系列cpu天梯图_2020年5月至强e5天梯图排行
  12. matlab fvtool 滤波器频响
  13. Unity编辑器修改图片的大小
  14. 去除枕头异味的两种方法
  15. java实现超时任务
  16. linux怎么下载dnw工具,Deepin Linux 安装dnw工具
  17. Vue-cli 脚手架一
  18. Ae动态模糊插件ReelSmart Motion Blur
  19. 现在如何注册台服服务器,《英雄联盟手游》台服账号注册教程 台服拳头账号注册步骤图解...
  20. 金蝶EAS DEP脚本(4)—— 控件常用脚本之设置F7默认值

热门文章

  1. angular中常见的管道及用法
  2. python输入二维数组_用Python生成二维数组的置换矩阵
  3. 查看linux系统重启时间
  4. EAI(Enterprise Application Integration,企业应用集成)
  5. 浅析ODS与EDW关系(转载)
  6. java 生成pdf文件_Java 中HTTP响应数据生成PDF,PDF文件的读取
  7. python iloc用法_pandas-03 DataFrame()中的iloc和loc用法
  8. Python之hasattr()函数介绍
  9. 字体凹陷效果html,AI如何做出凹陷效果 AI制作文字凹陷效果教程
  10. 子沐课堂——Flask留言板