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 ...
随机推荐
- (BFS)poj1465-Multiple
题目地址 题意可理解为我们有一些给定的元素,要用它们组成数,如果一个长度(x)所有组成的数都不是给定的另一个数(n)的倍数,并且长度为x的数中有模n的不同于长度小于x的数模n的数,那么继续延长这个数的 ...
- JavaScript中的逗号运算符
JavaScript逗号运算符 阅读本文的前提,明确表达式.短语.运算符.运算数这几个概念. 所谓表达式,就是一个JavaScript的“短语”,JavaScript解释器可以计算它,从而生成一个值 ...
- Charles的使用
简介 Charles是在Mac下常用的截取网络封包的工具,在做iOS开发时,我们为了调试与服务器端的网络通讯协议,常常需要截取网络封包来分析.Charles通过将自己设置成系统的网络访问代理服务器,使 ...
- Apache代理Tomcat实现session共享构建网上商城系统
一.环境介绍 二.安装配置后端服务器 三.安装配置前端服务器 四.配置Tomcat服务器实现session共享 五.构建网上商城系统 一.环境介绍 系统版本:CentOS 6.4_x86_64 Mys ...
- Introducing Windows 10 Editions(Windows10版本介绍)
Windows 10将在今年夏天正式发布,今天微软官方博客分享了一些Windows 10版本的细节.详见Introducing Windows 10 Editions Windows 10 HomeW ...
- Win7下通过eclipse远程连接CDH集群来执行相应的程序以及错误说明
最近尝试这用用eclipse连接CDH的集群,由于之前尝试过很多次都没连上,有一次发现Cloudera Manager是将连接的端口修改了,所以才导致连接不上CDH的集群,之前Apache hadoo ...
- css实现微信信息背景qq聊天气泡
用css实现一个椭圆形状的背景框很好实现 css: div{ width:200px; height:80px; background-color: #78DDF8; border-radius:10 ...
- 2015百度之星1002 查找有序序列(RMQ+主席树模板水过)
题意:求在数列中能找到几个个长度为k 的区间,里面的 k 个数字排完序后是连续的. 思路:枚举范围,判断区间内是否有重复的数字(主席树),没有的话求区间最大-区间最小(RMQ),判断是否等于K,是的话 ...
- brute-force search
#include <pcl/search/brute_force.h> #include <pcl/common/common.h> #include <iostream ...
- Model1
jsp+javabean的开发模式 此处JavaBean也可是封装的业务逻辑 流程: 浏览器端访问jsp,jsp交给Javabean处理,javabean处理后台数据,交还给Jsp