线段树+矩阵快速幂 Codeforces Round #373 (Div. 2) E
http://codeforces.com/contest/719/problem/E
题目大意:给你一串数组a,a[i]表示第i个斐波那契数列,有如下操作
①对[l,r]区间+一个val ②求出[l,r]区间的和。
定义区间的和为该区间内每个a[i]所对应的斐波那契数列的和。
思路:线段树保存区间val,和区间更新,用矩阵快速幂求解复杂度是m*logn*logk
//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 1e5 + ;
const LL mod = 1e9 + ;
struct Node{
LL mat[][];
void reset(){memset(mat, , sizeof(mat));}
void getone(){
reset();
mat[][] = mat[][] = ;
}
}; inline Node mul(Node A, Node B){
Node ans; ans.reset();
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
for (int k = ; k < ; k++)
ans.mat[i][j] = (ans.mat[i][j] + A.mat[i][k] * B.mat[k][j]) % mod;
return ans;
} inline Node add(Node a, Node b){
Node ans; ans.reset();
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
ans.mat[i][j] = (a.mat[i][j] + b.mat[i][j]) % mod;
return ans;
} inline Node kpow(LL k){
Node ans; ans.reset();
ans.mat[][] = ans.mat[][] = ;
Node A;
A.mat[][] = A.mat[][] = A.mat[][] = ;
A.mat[][] = ;
while (k){
if (k & ) ans = mul(ans, A);
A = mul(A, A);
k >>= ;
}
return ans;
} struct Mytree{
Node sum;
Node lazyk;
}tree[maxn << ]; int n, m; inline void push_up(int o){
int lb = o << , rb = o << | ;
tree[o].sum = add(tree[lb].sum, tree[rb].sum);
} void build_tree(int l, int r, int o){
if (l == r){
LL k; scanf("%lld", &k);
tree[o].sum = kpow(k);
tree[o].lazyk.getone();
return ;
}
tree[o].sum.reset(); tree[o].lazyk.getone();
int mid = (l + r) / ;
if (l <= mid) build_tree(l, mid, o << );
if (r > mid) build_tree(mid + , r, o << | );
push_up(o);
} inline void push_down(int o){
int lb = o << , rb = o << | ;
tree[lb].sum = mul(tree[lb].sum, tree[o].lazyk);
tree[lb].lazyk = mul(tree[lb].lazyk, tree[o].lazyk); tree[rb].sum = mul(tree[rb].sum, tree[o].lazyk);
tree[rb].lazyk = mul(tree[rb].lazyk, tree[o].lazyk); tree[o].lazyk.getone();
} void update(int l, int r, int ql, int qr, Node k, int o){
if (ql <= l && qr >= r){
tree[o].sum = mul(tree[o].sum, k);
tree[o].lazyk = mul(tree[o].lazyk, k);
return ;
}
int mid = (l + r) / ;
push_down(o);
if (ql <= mid) update(l, mid, ql, qr, k, o << );
if (qr > mid) update(mid + , r, ql, qr, k, o << | );
push_up(o);
return ;
} Node query(int l, int r, int ql, int qr, int o){
if (ql <= l && qr >= r){
return tree[o].sum;
}
push_down(o);
Node ans; ans.reset();
int mid = (l + r) / ;
if (ql <= mid) ans = add(query(l, mid, ql, qr, o << ), ans);
if (qr > mid) ans = add(query(mid + , r, ql, qr, o << | ), ans);
push_up(o);
return ans;
} int main(){
scanf("%d%d", &n, &m);
build_tree(, n, );
for (int i = ; i < m; i++){
int ty; scanf("%d", &ty);
if (ty == ){
int l, r; LL k;
scanf("%d%d%lld", &l, &r, &k);
update(, n, l, r, kpow(k), );
}
else if (ty == ){
int l, r; scanf("%d%d", &l, &r);
Node ans = query(, n, l, r, );
printf("%lld\n", ans.mat[][]);
}
}
return ;
}
线段树+矩阵快速幂 Codeforces Round #373 (Div. 2) E的更多相关文章
- Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)
题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...
- CF575A Fibonotci [线段树+矩阵快速幂]
题意 \(s\{\}\) 是一个循环数列 循环节为 \(n\),你可以改掉 \(m\) 项,这 \(m\) 项独立,且不影响循环节 考虑线段树维护矩阵,单点修改最多m次,每次矩阵快速幂就完事了 // ...
- CF719E(线段树+矩阵快速幂)
题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...
- [快速幂]Codeforces Round #576 (Div. 2)-C. MP3
C. MP3 time limit per test 1 second memory limit per test 256 megabytes input standard input output ...
- Codeforces Round #373 (Div. 1)
Codeforces Round #373 (Div. 1) A. Efim and Strange Grade 题意 给一个长为\(n(n \le 2 \times 10^5)\)的小数,每次可以选 ...
- Codeforces Round #373 (Div. 2)A B
Codeforces Round #373 (Div. 2) A. Vitya in the Countryside 这回做的好差啊,a想不到被hack的数据,b又没有想到正确的思维 = = [题目链 ...
- 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 ...
- [递推+矩阵快速幂]Codeforces 1117D - Magic Gems
传送门:Educational Codeforces Round 60 – D 题意: 给定N,M(n <1e18,m <= 100) 一个magic gem可以分裂成M个普通的gem ...
- 矩阵快速幂---BestCoder Round#8 1002
当要求递推数列的第n项且n很大时,怎么快速求得第n项呢?可以用矩阵快速幂来加速计算.我们可以用矩阵来表示数列递推公式比如fibonacci数列 可以表示为 [f(n) f(n-1)] = [f(n ...
随机推荐
- 一步一步学Linq to sql(三):增删改
示例数据库 字段名 字段类型 允许空 字段说明 ID uniqueidentifier 表主键字段 UserName varchar(50) 留言用户名 PostTime datetime 留言时间 ...
- LinqToExcel使用简介一
最近才看到原来也可以用Linq来访问Excel,功能还挺强大的.要使用这个功能,首先得下载一个LinqToExcel的相关文件,然后就可以调用相关的方法. 使用前面介 ...
- 「暑期训练」「基础DP」 Monkey and Banana (HDU-1069)
题意与分析 给定立方体(个数不限),求最多能堆叠(堆叠要求上方的方块严格小于下方方块)的高度. 表面上个数不限,问题是堆叠的要求决定了每个方块最多可以使用三次.然后就是对3n" role=& ...
- Jenkins - 持续集成部署
1. 安装svn:用于checkout源码 (1)yum 安装:yum -y install subversion (2)查看svn版本信息:svnserver --version 2. 安装jdk ...
- MySQL☞between ... and ...
between 初值 and 终值:求出该列列值在初值和终值之间所有的数据 格式如下: select 列名/* from 表名 where 列名 between 初值 and 终值 如下图:
- ajax 异步刷新,需要填写的参数
参数 options 类型:Object 可选.AJAX 请求设置.所有选项都是可选的. ******* async 类型:Boolean 默认值: true.默认设置下,所有请求均为异步请求.如果需 ...
- Week7 Teamework from Z.XML-NABC
NABC 引言:我们团队计划做一个手机端的类RPG2d游戏.之所以我们定义为类RPG,是因为我们希望弱化RPG在游戏中的概念--减少或者排除人物对话等较为无趣的内容,而将重点放在玩家的娱乐享受中.为了 ...
- android桌面悬浮窗仿QQ手机管家加速效果
主要还是用到了WindowManager对桌面悬浮进行管理. 需要一个火箭的悬浮窗 一个发射台悬浮窗 ,判断火箭是否放到了发射台,如果放上了,则使用AsyTask 慢慢将火箭的图片往上移.结束后., ...
- 如何理解流Stream
百度百科: 计算机中的流其实是一种信息的转换.它是一种有序流,因此相对于某一对象,通常我们把对象接收外界的信息输入(Input)称为输入流,相应地从对象向外输出(Output)信息为输出流,合称为输入 ...
- Linux arm64的虚拟内存布局
原创翻译,转载请注明出处. 页表转换arm64在硬件体系结构上支持4级的每页大小为4K的页表转换,也支持3级的页大小64KB的页表转换.在linux arm64中,如果页的大小为4KB,使用3级页表转 ...