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 矩阵快速幂 + 线段树的更多相关文章
- 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 ...
- Codeforces 719E [斐波那契区间操作][矩阵快速幂][线段树区间更新]
/* 题意:给定一个长度为n的序列a. 两种操作: 1.给定区间l r 加上某个数x. 2.查询区间l r sigma(fib(ai)) fib代表斐波那契数列. 思路: 1.矩阵操作,由矩阵快速幂求 ...
- 【XSY2524】唯一神 状压DP 矩阵快速幂 FFT
题目大意 给你一个网格,每个格子有概率是\(1\)或是\(0\).告诉你每个点是\(0\)的概率,求\(1\)的连通块个数\(\bmod d=0\)的概率. 最开始所有格子的概率相等.有\(q\)次修 ...
- Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)
题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...
- 线段树+矩阵快速幂 Codeforces Round #373 (Div. 2) E
http://codeforces.com/contest/719/problem/E 题目大意:给你一串数组a,a[i]表示第i个斐波那契数列,有如下操作 ①对[l,r]区间+一个val ②求出[l ...
- CF575A Fibonotci [线段树+矩阵快速幂]
题意 \(s\{\}\) 是一个循环数列 循环节为 \(n\),你可以改掉 \(m\) 项,这 \(m\) 项独立,且不影响循环节 考虑线段树维护矩阵,单点修改最多m次,每次矩阵快速幂就完事了 // ...
- hdu4965 Fast Matrix Calculation (矩阵快速幂 结合律
http://acm.hdu.edu.cn/showproblem.php?pid=4965 2014 Multi-University Training Contest 9 1006 Fast Ma ...
- 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也 ...
- 瓷砖铺放 (状压DP+矩阵快速幂)
由于方块最多涉及3行,于是考虑将每两行状压起来,dfs搜索每种状态之间的转移. 这样一共有2^12种状态,显然进行矩阵快速幂优化时会超时,便考虑减少状态. 进行两遍bfs,分别为初始状态可以到达的状态 ...
随机推荐
- Mysqldump参数大全 这 些参数 不同于 mysql 的那些参数(下边文章开头有链接) :2 种类型的参数含义是不一样的
Mysqldump参数大全 这 些参数 不同于 mysql 的那些参数 :2 种类型的参数含义是不一样的 Mysqldump参数大全(参数来源于mysql5.5.19源码) 参数 参数说明 --a ...
- 高级工程师-Java注解
高级工程师-Java注解 前言 代码,就是我们身为程序员的名片. 简洁,优雅,统一,是我们的追求. 优秀的代码,会给浏览者一种艺术的美感.如DL大神的JUC包,感兴趣的小伙伴,可以研究一下. 那么日常 ...
- vue单页应用和和多页应用的区别
个人见解如下: 单页面应用(SinglePage Web Application )简称:SPA 多页面应用 (MultiPage Application) 简称:MPA 组成一个外壳和多个页面片段 ...
- ubuntu允许root远程登录
之前说了,怎么设置root用户登录,但是使用Xshell等工具操作Ubuntu,用户登录不进去,原因很简单,没有开启root登录的权限. 1.检查ssh服务是否开启 使用以下命令,查看是否开启 ps ...
- python3购物车
python3实现购物车小程序,优化后将程序分成函数,用文件注册和验证用户名密码. #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 20 ...
- react: typescript import images alias
1.webpack.config.js resolve: { extensions: ["ts", "tsx", "js", "j ...
- TensorFlow keras dropout层
# 建立神经网络模型 model = keras.Sequential([ keras.layers.Flatten(input_shape=(28, 28)), # 将输入数据的形状进行修改成神经网 ...
- Java 虚拟机中的运行时数据区分析
本文基于 JDK1.8 阐述分析 运行过程 我们都知道 Java 源文件通过编译器编译后,能产生相应的 .Class 文件,也就是字节码文件.而字节码文件通过 Java 虚拟机中的解释器,编译成特定机 ...
- php微信公众号开发curl返回false
最近刚接触温馨公众号开发,在自定义菜单用curl请求时,碰到了一个小坑.一时半会没有解决,便去问度娘,谷歌.发现都是说$url里面有空格导致的失败. 然而我的并没有空格,一直返回false,这个时候我 ...
- curl请求本地域名问题
curl在本地虚拟机上请求本地接口时候,出现域名解析问题,换为ip即可,可用curl_error() 或者curl_errno来调试: vue单个文件在引入时候自己的逻辑js文件一定要放在html后引 ...