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,分别为初始状态可以到达的状态 ...
随机推荐
- 跳转语句break与continue的使用环境
break:改变程序控制流 常用于do-while.while.for .switch循环中,终止某个循环,程序跳转到循环块外的下一条语句 continue:跳出本次循环,进入下一次循环
- 第二章:shell变量
查看所有全局和局部变量:delare和set 查看所有全局变量:env 定义环境变量: 用户变量在家目录下的~/.bash_profile和~/.bashrc中设置 全局变量在/etc/profile ...
- 微信小程序 —搜索框
wxSearch优雅的微信小程序搜索框 一.功能 支持自定义热门key 支持搜索历史 支持搜索建议 支持搜索历史(记录)缓存 二.使用 1.将wxSearch文件夹整个拷贝到根目录下 2.引入 // ...
- adb命令查看手机应用内存使用情况
adb shell回车 一.procrank VSS >= RSS >= PSS >= USSVSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)是单个 ...
- vue element多文件多格式上传文件,后台springmvc完整代码
template: <el-upload class="upload-demo" ref=&quo ...
- [转载]深度理解Session
什么是session session的官方定义是:Session:在计算机中,尤其是在网络应用中,称为“会话控制”.Session 对象存储特定用户会话所需的属性及配置信息. 说白了session就是 ...
- Apache solr velocity模块 漏洞复现
0x01 Solr简单介绍 Solr是建立在Apache Lucene ™之上的一个流行.快速.开放源代码的企业搜索平台. Solr具有高度的可靠性,可伸缩性和容错能力,可提供分布式索引,复制和负载平 ...
- [PHP][thinkphp5] 学习一:增删改查
<?php namespace app\index\controller; use think\Controller; use think\Db; class Test extends Cont ...
- [数据库]Mysql蠕虫复制增加数据
将查询出来的数据插入到指定表中,例: 将查询user表数据添加到user表中,数据会成倍增加 insert into user(uname,pwd) select uname,pwd from use ...
- tensorflow1.0 队列FIFOQueue管理实现异步读取训练
import tensorflow as tf #模拟异步子线程 存入样本, 主线程 读取样本 # 1. 定义一个队列,1000 Q = tf.FIFOQueue(1000,tf.float32) # ...