Codeforces 719E [斐波那契区间操作][矩阵快速幂][线段树区间更新]
/*
题意:给定一个长度为n的序列a。
两种操作:
1.给定区间l r 加上某个数x.
2.查询区间l r sigma(fib(ai)) fib代表斐波那契数列。
思路:
1.矩阵操作,由矩阵快速幂求一个fib数根据矩阵的乘法结合率,A*C+B*C=(A+B)*C; 这样可以通过线段树维护某个区间2*1矩阵的和。
2.时限卡的紧...用我的矩阵乘法板子TLE了。所以把板子里边的三重循环改成手工公式...
3.注意(a+b)%mod。这种,改成if(a+b>=mod)a+b-mod这种形式时间几乎减半了==...(因为查询和更新操作每次都要把两个矩阵加起来...所以这种优化在这题来说作用明显)
4.注意lazy标记不要记录要乘多矩阵多少次方...而是直接记录该矩阵...这是最重要的一个优化(个人认为).因为每次向下层更新都要求一次矩阵...
*/
#include<bits/stdc++.h>
#define N 100020
#define MAXS 2
using namespace std;
long long jilu[N];
long long jil[N];
long long MOD =1e9+;
struct Matrix
{
long long mx[MAXS][MAXS];
Matrix()
{
memset(mx,,sizeof(mx));
}
Matrix operator* (const Matrix& b) const
{
Matrix tmp;
tmp.mx[][]=mx[][]*b.mx[][]+mx[][]*b.mx[][];
if(tmp.mx[][]>=MOD)tmp.mx[][]%=MOD;
tmp.mx[][]=mx[][]*b.mx[][]+mx[][]*b.mx[][];
if(tmp.mx[][]>=MOD)tmp.mx[][]%=MOD;
tmp.mx[][]=mx[][]*b.mx[][]+mx[][]*b.mx[][];
if(tmp.mx[][]>=MOD)tmp.mx[][]%=MOD;
tmp.mx[][]=mx[][]*b.mx[][]+mx[][]*b.mx[][];
if(tmp.mx[][]>=MOD)tmp.mx[][]%=MOD;
return tmp;
} Matrix operator +(const Matrix &b)const{
Matrix tmp;
for(int i=;i<;i++){
for(int j=;j<;j++){
tmp.mx[i][j]=(mx[i][j]+b.mx[i][j]);
if(tmp.mx[i][j]>=MOD)tmp.mx[i][j]-=MOD;
}
}
return tmp;
}
void initE()
{
memset(mx,, sizeof(mx));
for (int i= ; i< ; i++)
{
mx[i][i]=;
}
} Matrix mpow(long long k)
{
Matrix c,b;
c=(*this); b.initE();
while(k)
{
if(k&)
{
b=b*c;
}
c=c*c;
k>>=;
}
return b;
}
};
Matrix biao,ben;
struct tr{
Matrix val,tt;
long long aa;
int s,e;
};
tr tree[<<];
void build(int s,int e,int k){
tr &tmp=tree[k];
tmp.s=s;tmp.e=e;tmp.aa=;
tmp.tt.initE();
if(s==e){
tmp.val.mx[][]=jilu[s];
tmp.val.mx[][]=jil[s];
return;
}
int mid=(s+e)>>;
build(s,mid,k<<);
build(mid+,e,k<<|);
tmp.val=tree[k<<].val+tree[k<<|].val;
}
void add(int s,int e,int k,int num){
tr &tmp=tree[k];
if(s==tmp.s&&e==tmp.e){
Matrix ttt=biao.mpow(num);
tmp.tt=ttt*tmp.tt;
tmp.val=ttt*tmp.val;
tmp.aa+=num;
return;
}
if(tmp.aa){
tree[k<<].aa+=tmp.aa;
tree[k<<].val=tmp.tt*tree[k<<].val;
tree[k<<].tt=tmp.tt*tree[k<<].tt;
tree[k<<|].aa+=tmp.aa;
tree[k<<|].val=tmp.tt*tree[k<<|].val;
tree[k<<|].tt=tmp.tt*tree[k<<|].tt;
tmp.tt.initE();
tmp.aa=;
}
int mid=(tmp.s+tmp.e)>>;
if(e<=mid)add(s,e,k<<,num);
else if(s>mid)add(s,e,k<<|,num);
else{
add(s,mid,k<<,num);
add(mid+,e,k<<|,num);
}
tmp.val=tree[k<<].val+tree[k<<|].val;
}
long long query(int s,int e,int k){
tr &tmp=tree[k];
if(tmp.s==s&&tmp.e==e){
return tmp.val.mx[][];
}
if(tmp.aa){
tree[k<<].aa+=tmp.aa;
tree[k<<].val=tmp.tt*tree[k<<].val;
tree[k<<].tt=tmp.tt*tree[k<<].tt;
tree[k<<|].aa+=tmp.aa;
tree[k<<|].val=tmp.tt*tree[k<<|].val;
tree[k<<|].tt=tmp.tt*tree[k<<|].tt;
tmp.tt.initE();
tmp.aa=;
}
int mid=(tmp.s+tmp.e)>>;
if(e<=mid)return query(s,e,k<<);
else if(s>mid)return query(s,e,k<<|);
else return (query(s,mid,k<<)+query(mid+,e,k<<|))%MOD;
}
int main()
{
int n,m;
biao.mx[][]=biao.mx[][]=biao.mx[][]=;
ben.mx[][]=ben.mx[][]=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%lld",jilu+i);
if(jilu[i]==){
jil[i]=;
}
else if(jilu[i]==){
jilu[i]=;
jil[i]=;
}
else{
Matrix rel=biao.mpow(jilu[i]-)*ben;
jilu[i]=rel.mx[][];
jil[i]=rel.mx[][];
}
}
build(,n,);
for(int i=;i<=m;i++){
int typ,l,r,x;
scanf("%d",&typ);
if(typ==){
scanf("%d%d%d",&l,&r,&x);
add(l,r,,x);
}
else{
scanf("%d%d",&l,&r);
printf("%lld\n",query(l,r,));
}
}
}
Codeforces 719E [斐波那契区间操作][矩阵快速幂][线段树区间更新]的更多相关文章
- HDU 4549 M斐波那契数列(矩阵快速幂)
题目链接:M斐波那契数列 题意:$F[0]=a,F[1]=b,F[n]=F[n-1]*F[n-2]$.给定$a,b,n$,求$F[n]$. 题解:暴力打表后发现$ F[n]=a^{fib(n-1)} ...
- CodeForces - 450B Jzzhu and Sequences —— 斐波那契数、矩阵快速幂
题目链接:https://vjudge.net/problem/CodeForces-450B B. Jzzhu and Sequences time limit per test 1 second ...
- M斐波那契数列(矩阵快速幂+费马小定理)
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
- HDU 4549 M斐波那契数列(矩阵快速幂+费马小定理)
M斐波那契数列 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Submi ...
- 洛谷P1349 广义斐波那契数列(矩阵快速幂)
P1349 广义斐波那契数列 https://www.luogu.org/problemnew/show/P1349 题目描述 广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列.今给定 ...
- HDU——4549M斐波那契数列(矩阵快速幂+快速幂+费马小定理)
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Su ...
- P1962 斐波那契数列 【矩阵快速幂】
一.题目 P1962 斐波那契数列 二.分析 比较基础的递推式转换为矩阵递推,这里因为$n$会超出$int$类型,所以需要用矩阵快速幂加快递推. 三.AC代码 1 #include <bits/ ...
- 【洛谷P1962 斐波那契数列】矩阵快速幂+数学推导
来提供两个正确的做法: 斐波那契数列双倍项的做法(附加证明) 矩阵快速幂 一.双倍项做法 在偶然之中,在百度中翻到了有关于斐波那契数列的词条(传送门),那么我们可以发现一个这个规律$ \frac{F_ ...
- [luoguP1962] 斐波那契数列(矩阵快速幂)
传送门 解析详见julao博客连接 http://worldframe.top/2017/05/10/清单-数学方法-——-矩阵/ ——代码 #include <cstdio> #incl ...
随机推荐
- jquery事件代理
在jQuery中,事件代理是指:把事件绑定到父级元素,然后等待事件通过DOM冒泡到该元素时再执行. 在事件侦听过程中有两种触发事件的方式:事件捕获和事件冒泡.事件冒泡更快,效率更高. 事件捕获:事件在 ...
- C++二进制文件中读写bitset
这个比较简单,直接上代码: bitset< > *b = >(); bitset< > *c = >(); ofstream out("I:\\test. ...
- JAVA ,Map接口 ,迭代器Iterator
1. Map 接口概述 java.util.Map 接口描述了映射结构, Map 接口允许以键集.值集合或键 - 值映射关系集的形式查看某个映射的内容. Java 自带了各种 Map 类. 这些 ...
- ie 11 cookie 的值为空
昨天碰到ie 11上运行的程序时 登录老是登录不上去 一直是登录界面 最后检查半天发现时因为 权限验证登录时 获取cookie里的用户信息时 一直为空 便在网上查询资料 发现是因为ie11 里貌似 ...
- 在MacOX下安装python-opencv
下载好opencv之后 1. 在文件夹下新建一个release或build的文件夹: 2. cmake . make 3.在该build文件夹下 nano .bash_profile 把python的 ...
- HDU 3006
http://acm.hdu.edu.cn/showproblem.php?pid=3006 注意到集合内数字最大只有14,状态压缩一下,然后枚举出所有状态 #include <iostream ...
- Android 学习第3课,小例子
package temperature.convert; import java.util.Scanner; public class Converter { public static void m ...
- mysql常用&实用语句
Mysql是最流行的关系型数据库管理系统,也是目前最常用的数据库之一,掌握其常用的操作语句是必不可少的. 下面是自己总结的mysqp常用&实用的sql语句: 1.mysql -u root - ...
- 《JavaScript模式》第4章 函数
@by Ruth92(转载请注明出处) 第4章:函数 一.JavaScript 中函数的两个重要特征 函数是第一类对象,可以作为带有属性和方法的值以及参数进行传递: 函数提供了局部作用域,而其他大括号 ...
- flume+kafka+smart数据接入实施手册
1. 概述 本手册主要介绍了,一个将传统数据接入到Hadoop集群的数据接入方案和实施方法.供数据接入和集群运维人员参考. 1.1. 整体方案 Flume作为日志收集工具,监控一个文件目录或者一 ...