博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LOJ2980]「THUSCH 2017」大魔法师
阅读量:5109 次
发布时间:2019-06-13

本文共 3449 字,大约阅读时间需要 11 分钟。

题目链接:

\(A,B,C\)组成矩阵\([A,B,C]\),那么每一次操作就可以用矩阵表示:

  • \(A=A+B\)

\(\times \begin{bmatrix}1&0&0\\1&1&0\\0&0&1\end{bmatrix}\)

\(B=B+C,C=C+A\)类似。

  • \(A=A+v\)

\(+[v,0,0]\)

  • \(B=B*v\)

\(\times \begin{bmatrix}1&0&0\\0&v&0\\0&0&1\end{bmatrix}\)

  • \(C=v\)

\(\times \begin{bmatrix}1&0&0\\1&0&0\\0&0&0\end{bmatrix}\)

\(+[0,0,v]\)

然后线段树区间操作即可,注意优先级。

每一次乘法标记清空时要置为单位矩阵。

时间复杂度 \(O(27n\log n)\)

代码(常数爆炸):

#include 
#include
#include
#define rint register inttypedef long long ll;#define Getchar (p1==p2&&(p2=(p1=In)+fread(In,1,1<<21,stdin),p1==p2)?EOF:*p1++)char In[1<<21],*p1=In,*p2=In,Ch,Out[8000005],*Outp=Out,St[15],*Tp=St;inline int Getint(rint x=0){ while(!isdigit(Ch=Getchar)); for(;isdigit(Ch);Ch=Getchar)x=x*10+(Ch^48); return x;}inline void Putint(int x,const char c){ do *Tp++=x%10^48;while(x/=10); do *Outp++=*--Tp;while(Tp!=St); *Outp++=c;}const int Mod=998244353;inline int Add(int a,int b){return (a+=b)>=Mod?a-Mod:a;}struct Matrix{ int n,m,a[3][3]; inline void Clear(){memset(a,0,sizeof a);} inline Matrix(const int ns=0,const int ms=0){n=ns,m=ms,Clear();} inline void Init(const int ns,const int ms){n=ns,m=ms;} inline void IOne(){for(rint i=0;i
>1)void Build(int p,int l,int r){ Sum[p].Init(1,3),TMul[p].Init(3,3),TAdd[p].Init(1,3),TMul[p].IOne(); if(l==r){for(rint i=0;i<3;++i)Sum[p].a[0][i]=Getint();return;} Build(Lc,l,Mid),Build(Rc,Mid+1,r),Sum[p]=Sum[Lc]+Sum[Rc];}inline void Pushdown(int p,int l,int r){ TMul[Lc]=TMul[Lc]*TMul[p]; TMul[Rc]=TMul[Rc]*TMul[p]; TAdd[Lc]=TAdd[Lc]*TMul[p]+TAdd[p]; TAdd[Rc]=TAdd[Rc]*TMul[p]+TAdd[p]; Sum[Lc]=Sum[Lc]*TMul[p]+TAdd[p]*(Mid-l+1); Sum[Rc]=Sum[Rc]*TMul[p]+TAdd[p]*(r-Mid); TMul[p].Clear(),TAdd[p].Clear(),TMul[p].IOne();}inline void Modify(int p,int l,int r,int tl,int tr,const Matrix &o,int t)//t=0 Mul t=1 Add{ if(tl<=l&&r<=tr) { if(!t)TMul[p]=TMul[p]*o,TAdd[p]=TAdd[p]*o,Sum[p]=Sum[p]*o; else TAdd[p]=TAdd[p]+o,Sum[p]=Sum[p]+o*(r-l+1); return; } Pushdown(p,l,r); if(tl<=Mid)Modify(Lc,l,Mid,tl,tr,o,t); if(tr>Mid)Modify(Rc,Mid+1,r,tl,tr,o,t); Sum[p]=Sum[Lc]+Sum[Rc];}inline Matrix Query(int p,int l,int r,int tl,int tr){ if(tl<=l&&r<=tr)return Sum[p]; Pushdown(p,l,r); Matrix Res(1,3); if(tl<=Mid)Res=Query(Lc,l,Mid,tl,tr); if(tr>Mid)Res=Res+Query(Rc,Mid+1,r,tl,tr); return Res;}int main(){ freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); Build(1,1,n=Getint()),m=Getint(); Matrix M1(3,3),M2(3,3),M3(3,3),A4(1,3),M5(3,3),M6(3,3),A6(1,3),Res; M1.a[0][0]=1,M1.a[1][0]=1,M1.a[1][1]=1,M1.a[2][2]=1; M2.a[0][0]=1,M2.a[1][1]=1,M2.a[2][1]=1,M2.a[2][2]=1; M3.a[0][0]=1,M3.a[0][2]=1,M3.a[1][1]=1,M3.a[2][2]=1; M5.a[0][0]=1,M5.a[2][2]=1,M6.a[0][0]=1,M6.a[1][1]=1; for(rint op,l,r;m--;) { op=Getint(),l=Getint(),r=Getint(); if(op==1)Modify(1,1,n,l,r,M1,0); else if(op==2)Modify(1,1,n,l,r,M2,0); else if(op==3)Modify(1,1,n,l,r,M3,0); else if(op==4)A4.a[0][0]=Getint(),Modify(1,1,n,l,r,A4,1); else if(op==5)M5.a[1][1]=Getint(),Modify(1,1,n,l,r,M5,0); else if(op==6)A6.a[0][2]=Getint(),Modify(1,1,n,l,r,M6,0),Modify(1,1,n,l,r,A6,1); else Res=Query(1,1,n,l,r),Putint(Res.a[0][0],' '),Putint(Res.a[0][1],' '),Putint(Res.a[0][2],'\n'); } return fwrite(Out,1,Outp-Out,stdout),0;}

转载于:https://www.cnblogs.com/LanrTabe/p/11482928.html

你可能感兴趣的文章
常用的Javascript设计模式
查看>>
静态库
查看>>
关于hibernate查询结果类的封装
查看>>
突然感到人生很绝望_
查看>>
IIS7:通过脚本来配置ftp站点
查看>>
淘宝用户杭州30个小区分布,根据默认收货地址统计用户id
查看>>
一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
查看>>
北京信息科技大学第十一届程序设计竞赛(重现赛)I
查看>>
【转载】Android 的 Handler 机制实现原理分析
查看>>
scanf函数
查看>>
HTML5——新表单元素 表单属性 语义元素
查看>>
CSS3—— 分页 框大小 弹性盒子 多媒体查询 多媒体查询实例
查看>>
使用反射获取Android中隐藏的方法
查看>>
【原创】Leetcode -- Reverse Linked List II -- 代码随笔(备忘)
查看>>
人脸识别技术开发人证比对访客系统
查看>>
Android之人脸识别
查看>>
HDU 5340——Three Palindromes——————【manacher处理回文串】
查看>>
二叉树的下一个节点
查看>>
Nginx配置文件详细说明
查看>>
遇到的Mysql的一个坑
查看>>