CF718C Sasha and Array(线段树维护矩阵)
题解
(不会矩阵加速的先去学矩阵加速)
反正我想不到线段树维护矩阵。我太菜了。
我们在线段树上维护一个区间的斐波那契的列矩阵的和。
然后询问时提取每个符合题意列矩阵的答案项(不是列矩阵存了两项吗,一个是当前项,一个是用来递推的)
因为矩阵乘有结合律所以区间加这个操作就直接区间乘变换矩阵的x次方就行。
然后记得开long long
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const long long mod=1e9+;
const long long N=;
long long n,m;
struct jz{
long long a[][];
}e,h,be,f[N],ma;
struct tree{
long long l,r;
jz sum,lazy;
}tr[N*];
jz jzc(jz a,jz b,jz c){
for(long long i=;i<=;i++)
for(long long j=;j<=;j++)
for(long long k=;k<=;k++){
c.a[i][j]+=a.a[i][k]*b.a[k][j];
c.a[i][j]%=mod;
}
return c;
}
jz ksm(long long b,jz x){
jz ans;
ans=ma;
while(b){
if(b&){
ans=jzc(ans,x,h);
}
b>>=;
x=jzc(x,x,h);
}
return ans;
}
void update(long long now){
tr[now].sum.a[][]=(tr[now*].sum.a[][]+tr[now*+].sum.a[][])%mod;
tr[now].sum.a[][]=(tr[now*].sum.a[][]+tr[now*+].sum.a[][])%mod;
}
void build(long long l,long long r,long long now){
tr[now].l=l;tr[now].r=r;tr[now].lazy=ma;
if(l==r){
tr[now].sum=f[l];
return;
}
long long mid=(l+r)>>;
build(l,mid,now*);
build(mid+,r,now*+);
update(now);
}
bool pd(jz a,jz b){
for(long long i=;i<=;i++)
for(long long j=;j<=;j++)
if(a.a[i][j]!=b.a[i][j])return false;
return true;
}
void pushdown(long long now){
if(pd(tr[now].lazy,ma))return;
tr[now*].sum=jzc(tr[now*].sum,tr[now].lazy,h);
tr[now*+].sum=jzc(tr[now*+].sum,tr[now].lazy,h);
tr[now*].lazy=jzc(tr[now*].lazy,tr[now].lazy,h);
tr[now*+].lazy=jzc(tr[now*+].lazy,tr[now].lazy,h);
tr[now].lazy=ma;
}
void add(long long l,long long r,long long now,jz x){
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
tr[now].sum=jzc(tr[now].sum,x,h);
tr[now].lazy=x;
return;
}
long long mid=(tr[now].l+tr[now].r)>>;
if(l>mid)add(l,r,now*+,x);
else if(r<=mid)add(l,r,now*,x);
else{
add(l,mid,now*,x);
add(mid+,r,now*+,x);
}
update(now);
}
long long query(long long l,long long r,long long now){
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
return tr[now].sum.a[][];
}
long long mid=(tr[now].l+tr[now].r)>>;
if(l>mid)return query(l,r,now*+);
else if(r<=mid)return query(l,r,now*);
else return (query(l,mid,now*)+query(mid+,r,now*+))%mod;
}
int main(){
scanf("%lld%lld",&n,&m);
e.a[][]=;e.a[][]=e.a[][]=e.a[][]=;
be.a[][]=;be.a[][]=;
for(long long i=;i<=;i++)
for(long long j=;j<=;j++)
if(i==j)ma.a[i][j]=;
else ma.a[i][j]=;
for(long long i=;i<=n;i++){
long long x;
scanf("%lld",&x);
if(x==)f[i]=be;
else f[i]=jzc(be,ksm(x-,e),h);
}
build(,n,);
for(long long i=;i<=m;i++){
long long k;
scanf("%lld",&k);
if(k==){
long long l,r,x;
scanf("%lld%lld%lld",&l,&r,&x);
add(l,r,,ksm(x,e));
}
else{
long long l,r;
scanf("%lld%lld",&l,&r);
printf("%lld\n",query(l,r,));
}
}
return ;
}
CF718C Sasha and Array(线段树维护矩阵)的更多相关文章
- CF719E. Sasha and Array [线段树维护矩阵]
CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...
- Codeforces Round #373 (Div. 2) E. Sasha and Array 线段树维护矩阵
E. Sasha and Array 题目连接: http://codeforces.com/contest/719/problem/E Description Sasha has an array ...
- CF718C Sasha and Array 线段树 + 矩阵乘法
有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$ 直接求不好求,改成矩阵乘法的形式: $a_{i}=M^x\times ...
- CF718C Sasha and Array [线段树+矩阵]
我们考虑线性代数上面的矩阵知识 啊呸,是基础数学 斐波那契的矩阵就不讲了 定义矩阵 \(f_x\) 是第 \(x\) 项的斐波那契矩阵 因为 \(f_i * f_j = f_{i+j}\) 然后又因为 ...
- CF718C Sasha and Array 线段树+矩阵加速
正解:线段树 解题报告: 传送门! 首先这种斐波拉契,又到了1e9的范围,又是求和什么的,自然而然要想到矩阵加速昂 然后这里主要是考虑修改操作,ai+=x如果放到矩阵加速中是什么意思呢QAQ? 那不就 ...
- 线段树维护矩阵【CF718C】 Sasha and Array
Description 有一个长为\(n\)的数列\(a_{1},a_{2}...a_{n}\),你需要对这个数列维护如下两种操作: \(1\space l \space r\space x\) 表示 ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- Subsequence Count 2017ccpc网络赛 1006 dp+线段树维护矩阵
Problem Description Given a binary string S[1,...,N] (i.e. a sequence of 0's and 1's), and Q queries ...
- hdu 5068 线段树维护矩阵乘积
http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...
随机推荐
- MYSQL INT(N)以及zerofill的使用区别
MYSQL中,int(n)括号里面的数据n无论写成多少,都是占4个字节的空间,最多能够存10位数.N不代表能够存多少位数,显示宽度M与数据所占用空间,数值的范围无关. 如果在定义字段的时候指定zero ...
- Python学习之基本概念
1.Python是一种解释型语言.Python解释器通过“一次执行一条语句”的方式执行程序的. 2.Python用空白来组织程序,不像R等用大括号. 3.# 是Python的注释符号. 4.变量是按引 ...
- asp.net 汉字转拼音的车祸现场
asp.net 汉字转拼音 需求背景: 昨天遇到个问题,就是面对系统中集中性的要设置大批量的用户设置默认的用户名,密码,权限(角色),同时要求用户名是姓名的全拼,回头看看旁边那个哥们撸胳膊挽袖子准备一 ...
- sql server 更新满足条件的某一条记录
上图数据:SNum为”18004XXXXX000001K2GW 4000 L1C“,OffLineStation为“OP1010”的有两条数据,当where条件中为上述两者时会同时更新这两条数据,并不 ...
- [ Linux ] [ OS ] [ CPU ] Linux系統 OS, CPU, Memory, Disk
查看 linux 版本 及 Kernel 版本 指令: cat /etc/*-release http://benit.pixnet.net/blog/post/19390916-%E5%A6%82% ...
- Net Core链接数据库
原文 在Windows下,相信大家分分钟都可以搞定.而初次接触.net core + mysql可能需要注意些细节.首先打开vs2017新建一个asp.net core项目(选Web应用程序), 然后 ...
- 修复EJBInvokerServlet漏洞
1600/invoker/EJBInvokerServlet(存在命令执行) 修复方案: # 删除接口 # 设置中间件的访问控制权限,禁止web访问 /invoker 目录 http://www.cn ...
- Android 开发环境安装配置手册
本文指导,如何一步步搭建Android开发平台. 1 下载软件 n JDK 1.5+ 到 http://java.sun.com/javase/downloads/index.jsp 下载 n ...
- HDU 1548 A strange lift【BFS】
题意:给出一个电梯,给出它的层数f,给出起点s,终点g,以及在每一层能够上或者下w[i]层,问至少需要按多少次按钮到达终点. 和POJ catch that cow一样,直接用了那一题的代码,发现一直 ...
- MVC 设计模式
MVC 设计模式: 最早由 Trygve Teenskaug 在 1978 年提出,上世纪 80 年代是程序语言 Smalltalk 的一种内部架构.后来 MVC 被其他领域借鉴,成为了软件工程中的一 ...