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的更多相关文章

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

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

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

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

  3. CF719E(线段树+矩阵快速幂)

    题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...

  4. [快速幂]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 ...

  5. Codeforces Round #373 (Div. 1)

    Codeforces Round #373 (Div. 1) A. Efim and Strange Grade 题意 给一个长为\(n(n \le 2 \times 10^5)\)的小数,每次可以选 ...

  6. Codeforces Round #373 (Div. 2)A B

    Codeforces Round #373 (Div. 2) A. Vitya in the Countryside 这回做的好差啊,a想不到被hack的数据,b又没有想到正确的思维 = = [题目链 ...

  7. 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 ...

  8. [递推+矩阵快速幂]Codeforces 1117D - Magic Gems

    传送门:Educational Codeforces Round 60 – D   题意: 给定N,M(n <1e18,m <= 100) 一个magic gem可以分裂成M个普通的gem ...

  9. 矩阵快速幂---BestCoder Round#8 1002

    当要求递推数列的第n项且n很大时,怎么快速求得第n项呢?可以用矩阵快速幂来加速计算.我们可以用矩阵来表示数列递推公式比如fibonacci数列 可以表示为 [f(n)   f(n-1)] = [f(n ...

随机推荐

  1. LeetCode:7. Reverse Integer(Easy)

    题目要求:将给出的整数进行逆序输出 注意:整数的最大范围-2147483648-2147483647,当翻转后的数超出范围后返回0 思路:对给出的整数除以10,取余和取整:然后对取整部分继续取余和取整 ...

  2. Java重写构造方法

    public class TestSuper { public static void main(String[] args) { new ChildClass("alex", 1 ...

  3. MySQL☞Group By

    分组: group by 列名:根据某一列,把数据分成几组,经常对每一组的数据使用聚合函数,按照我的理解,该列有几种不同的值,那么就把该列分成几组,如下图 简单的来说,第二列中有两个不同的值a和b,那 ...

  4. COJ 2192: Wells弹键盘 (dp)

    2192: Wells弹键盘 Description Wells十分羡慕和佩服那些会弹钢琴的人比如子浩君,然而Wells只会弹键盘…… Wells的键盘只有10个键,从1,2,3,……,9,0,如下图 ...

  5. 机器学习 (二) 多变量线性回归 Linear Regression with Multiple Variables

    文章内容均来自斯坦福大学的Andrew Ng教授讲解的Machine Learning课程,本文是针对该课程的个人学习笔记,如有疏漏,请以原课程所讲述内容为准.感谢博主Rachel Zhang 的个人 ...

  6. [android]不解锁刷机

    本人因为误操作进入andriod recovery模式,显示failed to boot 2,致手机无法恢复出厂值, 当时那叫一个郁闷.上论坛搜寻无数,唉让刷底包的无数(在此不解释),万恶的刷底包. ...

  7. iOS-plist文件的写读

    NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"xiaoli" ofType:@"plist ...

  8. Pandoc中的Markdown语法

    概述 Pandoc中支持扩展修订版本的Markdown语法 使用pandoc中支持的Markdown语法用 -f markdown 使用标准Markdown语法用 -f markdown_strict ...

  9. 使用 TListView 控件(2)

    本例效果图: 代码文件: unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, ...

  10. 【bzoj4152】[AMPPZ2014]The Captain 堆优化Dijkstra

    题目描述 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 输入 第一行包含一个正整数n(2<=n< ...