E. Sasha and Array

这个题目没有特别难,需要自己仔细想想,一开始我想了一个方法,不对,而且还很复杂,然后lj提示了我一下说矩阵乘,然后再仔细想想就知道怎么写了。

这个就是直接把矩阵放到线段树里面去了。

注意优化,降低复杂度。

#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <queue>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int mod=1e9+;
struct mat
{
ll m[][];
}unite,zero; mat operator*(mat a,mat b){
mat ans;
for(int i=;i<=;i++){
for(int j=;j<=;j++){
ll x = ;
for(int k=;k<=;k++) x+=(a.m[i][k]*b.m[k][j])%mod;
ans.m[i][j]=x%mod;
}
}
return ans;
}
mat operator+(mat a,mat b){
mat ans;
for(int i=;i<=;i++)
for(int j=;j<=;j++)
ans.m[i][j]=(a.m[i][j]+b.m[i][j])%mod;
return ans;
} mat mod_pow(mat a,ll n){
mat ans=unite;
while(n){
if(n&) ans=ans*a;
a=a*a;
n>>=;
}
return ans;
} const int maxn=1e5+;
mat sum[maxn*],a,lazy[maxn*];
ll v[maxn]; void init(){
a.m[][]=a.m[][]=a.m[][]=,a.m[][]=;
for(int i=;i<;i++) unite.m[i][i]=;
for(int i=;i<;i++)
for(int j=;j<;j++) zero.m[i][j]=;
} void push_up(int id){
sum[id]=sum[id<<]+sum[id<<|];
} void build(int id,int l,int r){
lazy[id]=unite;
if(l==r){
sum[id]=mod_pow(a,v[l]);
return ;
}
int mid=(l+r)>>;
build(id<<,l,mid);
build(id<<|,mid+,r);
push_up(id);
} bool same(mat a,mat b){
for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(a.m[i][j]!=b.m[i][j]) return false;
}
}
return true;
} void push_down(int id){
if(same(lazy[id],unite)) return ;
sum[id<<]=sum[id<<]*lazy[id];
sum[id<<|]=sum[id<<|]*lazy[id];
lazy[id<<]=lazy[id<<]*lazy[id];
lazy[id<<|]=lazy[id<<|]*lazy[id];
lazy[id]=unite;
} void update(int id,int l,int r,int x,int y,mat val){
if(x<=l&&y>=r){
lazy[id]=lazy[id]*val;
sum[id]=sum[id]*val;
return ;
}
push_down(id);
int mid=(l+r)>>;
if(x<=mid) update(id<<,l,mid,x,y,val);
if(y>mid) update(id<<|,mid+,r,x,y,val);
push_up(id);
} mat query(int id,int l,int r,int x,int y){
if(x<=l&&y>=r) return sum[id];
mat ans=zero;
int mid=(l+r)>>;
push_down(id);
if(x<=mid) ans=ans+query(id<<,l,mid,x,y);
if(y>mid) ans=ans+query(id<<|,mid+,r,x,y);
return ans;
} int main(){
init();
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%lld",&v[i]);
build(,,n);
while(m--){
int opt;
ll l,r,x;
scanf("%d",&opt);
if(opt==){
scanf("%lld%lld%lld",&l,&r,&x);
mat val=mod_pow(a,x);
update(,,n,l,r,val);
}
else {
scanf("%lld%lld",&l,&r);
mat ans=query(,,n,l,r);
printf("%lld\n",ans.m[][]);
}
}
return ;
}

E. Sasha and Array 矩阵快速幂 + 线段树的更多相关文章

  1. Codeforces Round #373 (Div. 2) E. Sasha and Array 矩阵快速幂+线段树

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

  2. Codeforces 719E [斐波那契区间操作][矩阵快速幂][线段树区间更新]

    /* 题意:给定一个长度为n的序列a. 两种操作: 1.给定区间l r 加上某个数x. 2.查询区间l r sigma(fib(ai)) fib代表斐波那契数列. 思路: 1.矩阵操作,由矩阵快速幂求 ...

  3. 【XSY2524】唯一神 状压DP 矩阵快速幂 FFT

    题目大意 给你一个网格,每个格子有概率是\(1\)或是\(0\).告诉你每个点是\(0\)的概率,求\(1\)的连通块个数\(\bmod d=0\)的概率. 最开始所有格子的概率相等.有\(q\)次修 ...

  4. Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)

    题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...

  5. 线段树+矩阵快速幂 Codeforces Round #373 (Div. 2) E

    http://codeforces.com/contest/719/problem/E 题目大意:给你一串数组a,a[i]表示第i个斐波那契数列,有如下操作 ①对[l,r]区间+一个val ②求出[l ...

  6. CF575A Fibonotci [线段树+矩阵快速幂]

    题意 \(s\{\}\) 是一个循环数列 循环节为 \(n\),你可以改掉 \(m\) 项,这 \(m\) 项独立,且不影响循环节 考虑线段树维护矩阵,单点修改最多m次,每次矩阵快速幂就完事了 // ...

  7. hdu4965 Fast Matrix Calculation (矩阵快速幂 结合律

    http://acm.hdu.edu.cn/showproblem.php?pid=4965 2014 Multi-University Training Contest 9 1006 Fast Ma ...

  8. hdu 4291 2012成都赛区网络赛 矩阵快速幂 ***

    分析:假设g(g(g(n)))=g(x),x可能非常大,但是由于mod 10^9+7,所以可以求出x的循环节 求出x的循环节后,假设g(g(g(n)))=g(x)=g(g(y)),即x=g(y),y也 ...

  9. 瓷砖铺放 (状压DP+矩阵快速幂)

    由于方块最多涉及3行,于是考虑将每两行状压起来,dfs搜索每种状态之间的转移. 这样一共有2^12种状态,显然进行矩阵快速幂优化时会超时,便考虑减少状态. 进行两遍bfs,分别为初始状态可以到达的状态 ...

随机推荐

  1. spring 中 hibernate 的 2种 配置方式(新旧 2种方式)

    Spring对hibernate配置文件hibernate.cfg.xml的集成,来取代hibernate.cfg.xml的配置 Spring对hibernate配置文件hibernate.cfg.x ...

  2. 2019-07-31【机器学习】无监督学习之降维NMF算法 (人脸特征提取)

    代码 from numpy.random import RandomState #加载RandomState用于创建随机种子 import matplotlib.pyplot as plt from ...

  3. Android UIAutomator自动化测试

    描述:UiAutomator接口丰富易用,可以支持所有Android事件操作,事件操作不依赖于控件坐标,可以通过断言和截图验证正确性,非常适合做UI测试. UIAutomator不需要测试人员了解代码 ...

  4. 详解 List接口

    本篇博文所讲解的这两个类,都是泛型类(关于泛型,本人在之前的博文中提到过),我们在学习C语言时,对于数据的存储,用的差不多都是数组和链表. 但是,在Java中,链表就相对地失去了它的存在价值,因为Ja ...

  5. selenium 获取页面<input>标签的个数和各个属性的值

    获取页面某个标签的数量.id.name.class的值,来辅助定位         List<WebElement> lw =driver.findElements(By.tagName( ...

  6. Trie树-提高海量数据的模糊查询性能

    今天这篇文章源于上周在工作中解决的一个实际问题,它是个比较普遍的问题,无论做什么开发,估计都有遇到过.具体是这样的,我们有一份高校的名单(2657个),需要从海量的文章标题中找到包含这些高校的标题,其 ...

  7. 高性能的JavaScript,这是一个高级程序员必备的技能

    不知道大家有没有看过高性能JavaScript,这个书是一本好书,推荐有JavaScript的基础的同学可以看一看这本书. 下面是我根据这本书整理出来的知识: 1.将经常使用的对象成员.数组项.和域外 ...

  8. 2019-2020-1 20199325《Linux内核原理与分析》第十二周作业

    什么是ShellShock? Shellshock,又称Bashdoor,是在Unix中广泛使用的Bash shell中的一个安全漏洞,首次于2014年9月24日公开.许多互联网守护进程,如网页服务器 ...

  9. 监控CPU与GPU的工具

    1.sensor:可以显示包括cpu在内的所有传感器的当前读数 使用sensors可以检测到cpu的温度,风扇的风速度,电压等. 2.Glances使用Python写的跨平台的curses的检测工具. ...

  10. QtConcurrent::run() 只能运行参数个数不超过5的函数

    有时不得不看源码 qtconcurrentrun.h template <typename T, typename Param1, typename Arg1, typename Param2, ...