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门 ...
随机推荐
- 初窥RabbitMQ消息中间及SpringBoot整合
一:RabbitMQ简介 RabbitMQ介绍 RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用. 消息中间件最主要的作用是解耦,中间件最标准 ...
- LeetCode 905. Sort Array By Parity
905. Sort Array By Parity Given an array A of non-negative integers, return an array consisting of a ...
- python实现本地图片上传到服务区
本地图片上传到服务器,其本质上来讲,就是读取本地图片,复制到服务器,并返回服务器url 前端代码,用的form表单提交,form表单中包含两个文件选择表单元素,选择文件,点击提交按钮,提交form表单 ...
- 2198: 小P当志愿者送餐
题目描述 在ICPC程序设计大赛期间,小P作为志愿者的任务是给各个学校送盒饭,小P一次最多可以携带M份盒饭.总共有N个学校来参加比赛,这N个学校的休息点在一条笔直的马路边一字排开,路的一头是小P取盒饭 ...
- DevOps工程师到底做些什么?
我们之前已经听到很多谈论DevOps和DevOps世界的最新趋势的事情,但是就DevOps工程师本身,到底干些什么呢? 在最纯粹的存在形式上来说,DevOps工程师是为了加快开发和运营团队之间的交付效 ...
- Python3练习题 035:Project Euler 007:第10001个素数
import time def f(x): #判断 x 是否为素数,返回bool值 if x == 2: return True elif x <= 1: return False else: ...
- css 图片文字垂直居中
先来看张图片 相信很多css新手遇到过这种问题,就是当图片和文本显示在一行的时候,效果很奇葩,文字和图片没法对齐, 这时我们需要做的是: 1,先给块级元素设置 display: inline-bloc ...
- windows中dir命令
最近想用dos命令打印指定目录下的所有文件夹的完整路径.最终发现可用dir命令来实现.在此学习下dir的各项命令. 32位win7系统上,打印帮助文档. D:\test>dir /? 显示目录中 ...
- vue传参二
<template> <ul> <li v-for="(value,key,index) in list" :key="index" ...
- laravel依赖注入 容器
[看完就懂]Laravel 服务容器,IoC,DI DI DI就是常说的依赖注入,那么究竟什么是依赖注入呢? 打个比方,电脑(非笔记本哈)需要键盘和鼠标我们才能进行操作,这个‘需要’换句话说 ...