分析

在线段树上用\(4 \times 4\)的矩阵打标记。

代码

  1. #include <bits/stdc++.h>
  2. #define rin(i,a,b) for(register int i=(a);i<=(b);++i)
  3. #define irin(i,a,b) for(register int i=(a);i>=(b);--i)
  4. #define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
  5. typedef long long LL;
  6. using std::cin;
  7. using std::cout;
  8. using std::endl;
  9. inline int read(){
  10. int x=0,f=1;char ch=getchar();
  11. while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
  12. while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
  13. return x*f;
  14. }
  15. const int MAXN=250005;
  16. const LL MOD=998244353;
  17. int n,m,ql,qr;
  18. LL a[MAXN],b[MAXN],c[MAXN];
  19. struct Mat{
  20. LL a[4][4];
  21. Mat(){memset(a,0,sizeof a);}
  22. inline LL* operator [] (int x){return a[x];}
  23. inline friend Mat operator * (Mat x,Mat y){
  24. Mat ret;
  25. ret[0][0]=(ret[0][0]+x[0][0]*y[0][0])%MOD;
  26. ret[0][1]=(ret[0][1]+x[0][0]*y[0][1])%MOD;
  27. ret[0][2]=(ret[0][2]+x[0][0]*y[0][2])%MOD;
  28. ret[0][3]=(ret[0][3]+x[0][0]*y[0][3])%MOD;
  29. ret[0][0]=(ret[0][0]+x[0][1]*y[1][0])%MOD;
  30. ret[0][1]=(ret[0][1]+x[0][1]*y[1][1])%MOD;
  31. ret[0][2]=(ret[0][2]+x[0][1]*y[1][2])%MOD;
  32. ret[0][3]=(ret[0][3]+x[0][1]*y[1][3])%MOD;
  33. ret[0][0]=(ret[0][0]+x[0][2]*y[2][0])%MOD;
  34. ret[0][1]=(ret[0][1]+x[0][2]*y[2][1])%MOD;
  35. ret[0][2]=(ret[0][2]+x[0][2]*y[2][2])%MOD;
  36. ret[0][3]=(ret[0][3]+x[0][2]*y[2][3])%MOD;
  37. ret[0][0]=(ret[0][0]+x[0][3]*y[3][0])%MOD;
  38. ret[0][1]=(ret[0][1]+x[0][3]*y[3][1])%MOD;
  39. ret[0][2]=(ret[0][2]+x[0][3]*y[3][2])%MOD;
  40. ret[0][3]=(ret[0][3]+x[0][3]*y[3][3])%MOD;
  41. ret[1][0]=(ret[1][0]+x[1][0]*y[0][0])%MOD;
  42. ret[1][1]=(ret[1][1]+x[1][0]*y[0][1])%MOD;
  43. ret[1][2]=(ret[1][2]+x[1][0]*y[0][2])%MOD;
  44. ret[1][3]=(ret[1][3]+x[1][0]*y[0][3])%MOD;
  45. ret[1][0]=(ret[1][0]+x[1][1]*y[1][0])%MOD;
  46. ret[1][1]=(ret[1][1]+x[1][1]*y[1][1])%MOD;
  47. ret[1][2]=(ret[1][2]+x[1][1]*y[1][2])%MOD;
  48. ret[1][3]=(ret[1][3]+x[1][1]*y[1][3])%MOD;
  49. ret[1][0]=(ret[1][0]+x[1][2]*y[2][0])%MOD;
  50. ret[1][1]=(ret[1][1]+x[1][2]*y[2][1])%MOD;
  51. ret[1][2]=(ret[1][2]+x[1][2]*y[2][2])%MOD;
  52. ret[1][3]=(ret[1][3]+x[1][2]*y[2][3])%MOD;
  53. ret[1][0]=(ret[1][0]+x[1][3]*y[3][0])%MOD;
  54. ret[1][1]=(ret[1][1]+x[1][3]*y[3][1])%MOD;
  55. ret[1][2]=(ret[1][2]+x[1][3]*y[3][2])%MOD;
  56. ret[1][3]=(ret[1][3]+x[1][3]*y[3][3])%MOD;
  57. ret[2][0]=(ret[2][0]+x[2][0]*y[0][0])%MOD;
  58. ret[2][1]=(ret[2][1]+x[2][0]*y[0][1])%MOD;
  59. ret[2][2]=(ret[2][2]+x[2][0]*y[0][2])%MOD;
  60. ret[2][3]=(ret[2][3]+x[2][0]*y[0][3])%MOD;
  61. ret[2][0]=(ret[2][0]+x[2][1]*y[1][0])%MOD;
  62. ret[2][1]=(ret[2][1]+x[2][1]*y[1][1])%MOD;
  63. ret[2][2]=(ret[2][2]+x[2][1]*y[1][2])%MOD;
  64. ret[2][3]=(ret[2][3]+x[2][1]*y[1][3])%MOD;
  65. ret[2][0]=(ret[2][0]+x[2][2]*y[2][0])%MOD;
  66. ret[2][1]=(ret[2][1]+x[2][2]*y[2][1])%MOD;
  67. ret[2][2]=(ret[2][2]+x[2][2]*y[2][2])%MOD;
  68. ret[2][3]=(ret[2][3]+x[2][2]*y[2][3])%MOD;
  69. ret[2][0]=(ret[2][0]+x[2][3]*y[3][0])%MOD;
  70. ret[2][1]=(ret[2][1]+x[2][3]*y[3][1])%MOD;
  71. ret[2][2]=(ret[2][2]+x[2][3]*y[3][2])%MOD;
  72. ret[2][3]=(ret[2][3]+x[2][3]*y[3][3])%MOD;
  73. ret[3][0]=(ret[3][0]+x[3][0]*y[0][0])%MOD;
  74. ret[3][1]=(ret[3][1]+x[3][0]*y[0][1])%MOD;
  75. ret[3][2]=(ret[3][2]+x[3][0]*y[0][2])%MOD;
  76. ret[3][3]=(ret[3][3]+x[3][0]*y[0][3])%MOD;
  77. ret[3][0]=(ret[3][0]+x[3][1]*y[1][0])%MOD;
  78. ret[3][1]=(ret[3][1]+x[3][1]*y[1][1])%MOD;
  79. ret[3][2]=(ret[3][2]+x[3][1]*y[1][2])%MOD;
  80. ret[3][3]=(ret[3][3]+x[3][1]*y[1][3])%MOD;
  81. ret[3][0]=(ret[3][0]+x[3][2]*y[2][0])%MOD;
  82. ret[3][1]=(ret[3][1]+x[3][2]*y[2][1])%MOD;
  83. ret[3][2]=(ret[3][2]+x[3][2]*y[2][2])%MOD;
  84. ret[3][3]=(ret[3][3]+x[3][2]*y[2][3])%MOD;
  85. ret[3][0]=(ret[3][0]+x[3][3]*y[3][0])%MOD;
  86. ret[3][1]=(ret[3][1]+x[3][3]*y[3][1])%MOD;
  87. ret[3][2]=(ret[3][2]+x[3][3]*y[3][2])%MOD;
  88. ret[3][3]=(ret[3][3]+x[3][3]*y[3][3])%MOD;
  89. return ret;
  90. }
  91. inline friend Mat operator + (Mat x,Mat y){
  92. Mat ret;
  93. ret[0][0]=(x[0][0]+y[0][0])%MOD;
  94. ret[0][1]=(x[0][1]+y[0][1])%MOD;
  95. ret[0][2]=(x[0][2]+y[0][2])%MOD;
  96. ret[0][3]=(x[0][3]+y[0][3])%MOD;
  97. return ret;
  98. }
  99. inline bool check(){
  100. if(a[0][0]!=1||a[1][1]!=1||a[2][2]!=1||a[3][3]!=1) return true;
  101. if(a[0][1]||a[0][2]||a[0][3]||a[1][0]||a[1][2]||a[1][3]||a[2][0]||a[2][1]||a[2][3]||a[3][0]||a[3][1]||a[3][2]) return true;
  102. return false;
  103. }
  104. }unit,optm[4],kk,seg[MAXN<<2],tag[MAXN<<2];
  105. #define mid ((l+r)>>1)
  106. #define lc (o<<1)
  107. #define rc ((o<<1)|1)
  108. inline void pushtag(int o,Mat y){
  109. seg[o]=seg[o]*y;
  110. tag[o]=tag[o]*y;
  111. }
  112. inline void pushdown(int o){
  113. if(!tag[o].check()) return;
  114. pushtag(lc,tag[o]);
  115. pushtag(rc,tag[o]);
  116. tag[o]=unit;
  117. }
  118. void build(int o,int l,int r){
  119. tag[o]=unit;
  120. if(l==r){
  121. seg[o][0][0]=a[l];
  122. seg[o][0][1]=b[l];
  123. seg[o][0][2]=c[l];
  124. seg[o][0][3]=1;
  125. return;
  126. }
  127. build(lc,l,mid);
  128. build(rc,mid+1,r);
  129. seg[o]=seg[lc]+seg[rc];
  130. }
  131. void upd(int o,int l,int r){
  132. if(ql<=l&&r<=qr){pushtag(o,kk);return;}
  133. pushdown(o);
  134. if(mid>=ql) upd(lc,l,mid);
  135. if(mid<qr) upd(rc,mid+1,r);
  136. seg[o]=seg[lc]+seg[rc];
  137. }
  138. Mat query(int o,int l,int r){
  139. if(ql<=l&&r<=qr) return seg[o];
  140. pushdown(o);
  141. if(mid<ql) return query(rc,mid+1,r);
  142. else if(mid>=qr) return query(lc,l,mid);
  143. else return query(lc,l,mid)+query(rc,mid+1,r);
  144. }
  145. #undef mid
  146. #undef lc
  147. #undef rc
  148. int main(){
  149. rin(i,0,3) unit[i][i]=1;
  150. rin(i,1,3) optm[i]=unit;
  151. optm[1][1][0]=1;
  152. optm[2][2][1]=1;
  153. optm[3][0][2]=1;
  154. n=read();
  155. rin(i,1,n) a[i]=read(),b[i]=read(),c[i]=read();
  156. build(1,1,n);
  157. m=read();
  158. while(m--){
  159. int opt=read();ql=read(),qr=read();
  160. if(opt<=3) kk=optm[opt];
  161. else if(opt==4) kk=unit,kk[3][0]=read();
  162. else if(opt==5) kk=unit,kk[1][1]=read();
  163. else if(opt==6) kk=unit,kk[2][2]=0,kk[3][2]=read();
  164. else{
  165. Mat ans=query(1,1,n);
  166. printf("%lld %lld %lld\n",ans[0][0],ans[0][1],ans[0][2]);
  167. continue;
  168. }
  169. upd(1,1,n);
  170. }
  171. return 0;
  172. }

[THUSC2017]大魔法师:线段树的更多相关文章

  1. [LOJ#2980][THUSCH2017]大魔法师(线段树+矩阵)

    每个线段树维护一个行向量[A,B,C,len]分别是这个区间的A,B,C区间和与区间长度,转移显然. 以及此题卡常,稍微哪里写丑了就能100->45. #include<cstdio> ...

  2. LOJ 2980 「THUSCH 2017」大魔法师——线段树

    题目:https://loj.ac/problem/2980 线段树维护矩阵. 然后是 30 分.似乎是被卡常了?…… #include<cstdio> #include<cstri ...

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

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

  4. 【BZOJ-4530】大融合 线段树合并

    4530: [Bjoi2014]大融合 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 280  Solved: 167[Submit][Status] ...

  5. [BZOI2014]大融合——————线段树进阶

    竟然改了不到一小时就改出来了, 可喜可贺 Description Solution 一开始想的是边两侧简单路径之和的乘积,之后发现这是个树形结构,简单路径数就是节点数. 之后的难点就变成了如何求线段树 ...

  6. zhw大神线段树姿势

    ; i<; i++) tree[i][]=tree[i][]=i; ; i>=; i--) tree[i][]=tree[i+i][], tree[i][]=tree[i+i+][]; v ...

  7. HDU 5091---Beam Cannon(线段树+扫描线)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...

  8. HDU1199 动态线段树 // 离散化

    附动态线段树AC代码 http://acm.hdu.edu.cn/showproblem.php?pid=1199 因为昨天做了一道动态线段树的缘故,今天遇到了这题没有限制范围的题就自然而然想到了动态 ...

  9. [CodeChef - STREETTA] The Street 李超线段树

    大致题意: 给出两个序列A,B,A初始为负无穷,B初始为0,有三种操作 1.在A上区间[u,v]上加一个等差数列,取与原本A序列的最大值. 2.在B上区间[u,v]上加一个等差数列. 3.给出一个点X ...

随机推荐

  1. 插入数据库失败([Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version)

    报错信息如下: , ) 原因,read是数据库的关键字, 牢记,如果一个词是数据库的关键字,那么在写数据库语句的时候,这个词一定是蓝色的(关键字颜色)!!

  2. 为什么只有ip地址和端口号需要主机字节序到网络字节序的转换?

    答复是:因为内容是二进制流,不是整数. 整数(int.uint16.uint32)的表达,是需要多字节的,在不同cpu上,字节次序是不同的.因此,从A主机到B主机,如果是异构的,就需要做字节调整.同构 ...

  3. Git+码云安装

    注册码云 1.1 下载git https://git-scm.com 1.2 安装 git安装一直next 下一步就行 1.3 测试 1.4 git原理

  4. 细说vue axios登录请求拦截器

    当我们在做接口请求时,比如判断登录超时时候,通常是接口返回一个特定的错误码,那如果我们每个接口都去判断一个耗时耗力,这个时候我们可以用拦截器去进行统一的http请求拦截. 1.安装配置axios cn ...

  5. uni-app如何编写底部导航栏

    在pages.json中配置代码如下: { "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocat ...

  6. mybatis 动态SQL查询总结

    背景 ××项目需要提供系统部分函数第三方调用接口,基于安全性和避免暴露数据库表信息的基础上进行函数接口的设计,根据第三方调用身份的权限提供某张表的自定义集合.本项目基于mybatis的持久层框架,支持 ...

  7. 删除表A的记录时,Oracle 报错:“ORA-02292:违反完整约束条件(XXX.FKXXX)- 已找到子记录

    1.找到以”FKXXX“为外键的表A的子表,直接运行select a.constraint_name, a.table_name, b.constraint_name from user_constr ...

  8. win10将mongodb加入系统服务,官方源码报错问题记录

    进入C:\Program Files\MongoDB\Server\3.6目录下 1.编写配置文件mongodb.cfg: dbpath=D:\MongoDB\data\db #数据库路径 logpa ...

  9. (转) oracle清空数据库脚本

    在开发过程中,可能经常需要重新初始化数据库,在初始化之前,我们肯定希望不再有以前的老表.存储过程等用户对象,用下面的教本就可以做到这一点: BEGIN     FOR rec IN     (SELE ...

  10. PCRE does not support \L, \l, \N{name}, \U, or \u...

    PCRE does not support \L, \l, \N{name}, \U, or \u... 参考文章:YCSUNNYLIFE 的 <php 正则匹配中文> 一.报错情景: 使 ...