LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)
线段树每个节点维护(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大魔法师(线段树+矩阵乘法)的更多相关文章
- [LOJ#2980][THUSCH2017]大魔法师(线段树+矩阵)
每个线段树维护一个行向量[A,B,C,len]分别是这个区间的A,B,C区间和与区间长度,转移显然. 以及此题卡常,稍微哪里写丑了就能100->45. #include<cstdio> ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- hdu 5068(线段树+矩阵乘法)
矩阵乘法来进行所有路径的运算, 线段树来查询修改. 关键还是矩阵乘法的结合律. Harry And Math Teacher Time Limit: 5000/3000 MS (Java/Others ...
- 【对不同形式矩阵的总结】WC 2009 最短路径问题(线段树+矩阵乘法)
题意 题目链接:https://www.luogu.org/problem/P4150 一个 \(6\times n\) 的网格图,每个格点有一个初始权值.有两种操作: 修改一个格子的权值 求 ...
- MAZE(2019年牛客多校第二场E题+线段树+矩阵乘法)
题目链接 传送门 题意 在一张\(n\times m\)的矩阵里面,你每次可以往左右和下三个方向移动(不能回到上一次所在的格子),\(1\)表示这个位置是墙,\(0\)为空地. 现在有\(q\)次操作 ...
- CF718C Sasha and Array 线段树 + 矩阵乘法
有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$ 直接求不好求,改成矩阵乘法的形式: $a_{i}=M^x\times ...
- LOJ 2980 「THUSCH 2017」大魔法师——线段树
题目:https://loj.ac/problem/2980 线段树维护矩阵. 然后是 30 分.似乎是被卡常了?…… #include<cstdio> #include<cstri ...
- Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门 Portal 原题目描述在最下面. 简单的 ...
- HDU 5068 Harry And Math Teacher 线段树+矩阵乘法
题意: 一栋楼有n层,每一层有2个门,每层的两个门和下一层之间的两个门之间各有一条路(共4条). 有两种操作: 0 x y : 输出第x层到第y层的路径数量. 1 x y z : 改变第x层 的 y门 ...
随机推荐
- Grafana+Prometheus打造全方位立体监控系统
前言 本文主要介绍如何使用Grafana和Prometheus以及node_exporter对Linux服务器性能进行监控.下面两张图分别是两台服务器监控信息: 服务器A 服务器B 概述 Promet ...
- ML.NET 示例:回归之价格预测
写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...
- 【中文版 | 论文原文】BERT:语言理解的深度双向变换器预训练
BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding 谷歌AI语言组论文<BERT:语言 ...
- 十五、bootstrap-select的使用方法
参考来源https://www.cnblogs.com/nianyifenzhizuo/p/8119462.html 需要的css和js <link rel="stylesheet&q ...
- H5 36-背景定位属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Ubuntu 14.04 安装caffe
仅支持CPU模式 sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-ser ...
- PS滤镜制作下雨照片特效
原图 一.打开你想要添加下雨效果的照片,并新建一个图层,命名为雨,填充为黑色,对“雨”层执行:滤镜 > 杂色> 添加杂色,参数如图. 二.对“雨”层执行:滤镜 > 模糊 > 高 ...
- Linux之查看系统配置命令
1.查看CPU个数: [root@ifusion ~]# lscpu 2.查看CPU进程数.核数: [root@ifusion ~]# cat /proc/cpuinfo 3.查看内存总量: [roo ...
- PHP中多个文件包含的问题 (一)
使用require或者include来包含文件时,包含的文件的内容相对性,这个很容易搞混,所以记录一下. 这个相对性包括 __DIR__,__FILE__,$_SERVER['PHP_SELF'],$ ...
- 在Linux添加PYTHONPATH方法以及修改环境变量方法
Linux下设置环境变量有三种方法,一种用于当前终端,一种用于当前用户,一种用于所有用户: 一:用于当前终端: 在当前终端中输入: export PATH=$PATH:<你的要加入的路径> ...