线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 250010
#define P 998244353
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m;
struct matrix
{
int n,a[4][4];
matrix operator *(const matrix&b) const
{
matrix c;c.n=n;memset(c.a,0,sizeof(c.a));
for (int i=0;i<n;i++)
for (int k=0;k<4;k++)
for (int j=0;j<4;j++)
c.a[i][j]=(c.a[i][j]+1ll*a[i][k]*b.a[k][j])%P;
return c;
}
matrix operator +(const matrix&b) const
{
matrix c;c.n=n;memset(c.a,0,sizeof(c.a));
for (int i=0;i<n;i++)
for (int j=0;j<4;j++)
c.a[i][j]=(a[i][j]+b.a[i][j])%P;
return c;
}
void print()
{
cout<<n<<endl;
for (int i=0;i<n;i++)
{
for (int j=0;j<4;j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
}
};
int L[N<<2],R[N<<2],a[N],b[N],c[N];
bool islazy[N<<2];
matrix tree[N<<2],lazy[N<<2],f,I;
void up(int k){tree[k]=tree[k<<1]+tree[k<<1|1];}
void build(int k,int l,int r)
{
L[k]=l,R[k]=r;lazy[k]=I;
if (l==r) {tree[k].n=1,tree[k].a[0][0]=a[l],tree[k].a[0][1]=b[l],tree[k].a[0][2]=c[l],tree[k].a[0][3]=1;return;}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
up(k);
}
void update(int k,matrix x)
{
tree[k]=tree[k]*x;
lazy[k]=lazy[k]*x;
islazy[k]=1;
}
void down(int k)
{
update(k<<1,lazy[k]);
update(k<<1|1,lazy[k]);
lazy[k]=I;islazy[k]=0;
}
void modify(int k,int l,int r,matrix x)
{
if (L[k]==l&&R[k]==r) {update(k,x);return;}
if (islazy[k]) down(k);
int mid=L[k]+R[k]>>1;
if (r<=mid) modify(k<<1,l,r,x);
else if (l>mid) modify(k<<1|1,l,r,x);
else modify(k<<1,l,mid,x),modify(k<<1|1,mid+1,r,x);
up(k);
}
matrix query(int k,int l,int r)
{
if (L[k]==l&&R[k]==r) return tree[k];
if (islazy[k]) down(k);
int mid=L[k]+R[k]>>1;
if (r<=mid) return query(k<<1,l,r);
else if (l>mid) return query(k<<1|1,l,r);
else return query(k<<1,l,mid)+query(k<<1|1,mid+1,r);
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
for (int i=1;i<=n;i++) a[i]=read(),b[i]=read(),c[i]=read();
I.n=4;for (int i=0;i<4;i++) I.a[i][i]=1;
build(1,1,n);f.n=4;
m=read();
for (int i=1;i<=m;i++)
{
int op=read(),l=read(),r=read();
memset(f.a,0,sizeof(f.a));
if (op==1) f.a[0][0]=f.a[1][1]=f.a[2][2]=f.a[3][3]=f.a[1][0]=1;
if (op==2) f.a[0][0]=f.a[1][1]=f.a[2][2]=f.a[3][3]=f.a[2][1]=1;
if (op==3) f.a[0][0]=f.a[1][1]=f.a[2][2]=f.a[3][3]=f.a[0][2]=1;
if (op==4) f.a[0][0]=f.a[1][1]=f.a[2][2]=f.a[3][3]=1,f.a[3][0]=read();
if (op==5) f.a[0][0]=f.a[2][2]=f.a[3][3]=1,f.a[1][1]=read();
if (op==6) f.a[0][0]=f.a[1][1]=f.a[3][3]=1,f.a[3][2]=read();
if (op!=7) modify(1,l,r,f);
else
{
matrix ans=query(1,l,r);
printf("%d %d %d\n",ans.a[0][0],ans.a[0][1],ans.a[0][2]);
}
}
return 0;
//NOTICE LONG LONG!!!!!
}

  

LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 跨域访问-需要设置HTTP响应标头

    前提:服务端网站的配置(被请求的网站) 1.需要在IIS服务器站点的功能视图中设置HTTP响应标头: 2.双击“HTTP响应标头”进入设置界面 3.点击右侧添加按钮弹出窗口 4.填入需要设置的信息 名 ...

  2. eletron打包

    https://www.cnblogs.com/BigJ/p/electron.html https://www.cnblogs.com/kakayang/p/9559777.html

  3. flask 更新数据库

    在做项目的过程中,我们都遇到过,经常需要修改我们数据库的字段,在flask中,是通过ORM(对象关系映射)来创建数据库的,表--->model class,字段---->属性 在flask ...

  4. koa-router

    为了处理URL,我们需要引入koa-router这个middleware,让它负责处理URL映射. 我们把上一节的hello-koa工程复制一份,重命名为url-koa. 先在package.json ...

  5. 2017百度软研(C++)

    问了很多,不过很多也都没有问到,感觉有点偏,很深入的东西,越问越虚.第一次实习面试从百度开始,也从百度结束吧.看得见的差距,不想将就,所以还是拿最后一次机会去尝试.win or go home, 所以 ...

  6. mybatis入门 配置文件解释 及测试

    这里介绍一下mybatis  根据mybatis的官网说明,mybatis是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置 ...

  7. POJ - 3264 线段树模板题 询问区间最大最小值

    这是线段树的一个模板题,给出一串数字,然后询问区间的最大最小值. 这个其实很好办,只需把线段树的节点给出两个权值,一个是区间的最小值,一个是区间的最大值,初始化为负无穷和正无穷,然后通过不断地输入节点 ...

  8. 反射reflect

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...

  9. mysql_查的小理解

    show create table employee; 对这个语句的小理解: 顿悟呀,之前一直不太理解这条语句,现在忽然觉得明朗起来.他就是展示创建这个表格时的SQL语句.执行上述代码之后结果如下: ...

  10. 修改eclipce操作权限

    <dependencies> <dependency> <groupId>jdk.tools</groupId> <artifactId>j ...