【题目链接】:http://codeforces.com/contest/719/problem/E

【题意】



给你一个数列,有两种操作1 l r x 给[l,r]区间上的数加上x, 2 l r 询问[l,r]区间fibonacci数列的和(f[l]+f[l+1]+……f[r])

【题解】



斐波那契数列有个矩阵乘法公式

f[n]=

[0 1] ^n× [0 0]
[1 1] [0 1]

最后得到的矩阵A

A[1][2]就是答案;(即第一行第二列)



写个线段树的成段更新;

用懒惰标记记录加上的数字x对应的A^x

维护区间的矩阵和就好;

新增加的A^x不要每次都重新算,不然会T





【Number Of WA】



9



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1e5+100; const int G = 2; //�����С
const int MOD = 1e9 + 7; //�
struct MX
{
LL v[G+1][G+1];
void O() { ms(v, 0); }
void E() { ms(v, 0); for (int i = 1; i <= G; ++i)v[i][i] = 1; }
MX operator * (const MX &b) const
{
MX c; c.O();
for (int k = 1; k <= G; ++k)
{
for (int i = 1; i <= G; ++i) if (v[i][k])
{
for (int j = 1; j <= G; ++j)
{
c.v[i][j] = (c.v[i][j] + (LL)v[i][k] * b.v[k][j]) % MOD;
}
}
}
return c;
}
MX operator + (const MX &b) const
{
MX c; c.O();
for (int i = 1; i <= G; ++i)
{
for (int j = 1; j <= G; ++j)
{
c.v[i][j] = (v[i][j] + b.v[i][j]) % MOD;
}
}
return c;
}
MX operator ^ (LL p) const
{
MX y; y.E();
MX x; memcpy(x.v, v, sizeof(v));
while (p)
{
if (p&1) y = y*x;
x = x*x;
p>>=1;
}
return y;
}
}A,v,cur; int n,m,flag[N<<2];
MX sum[N<<2],lazy_tag[N<<2];
LL a[N]; inline void push_up(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
} void build(int l,int r,int rt)
{
lazy_tag[rt].E();
if (l==r)
{
sum[rt] = A^a[l];
return;
}
int m = (l+r)>>1;
build(lson),build(rson);
push_up(rt);
} inline void push_down(int rt)
{
if (!flag[rt]) return;
flag[rt<<1] = flag[rt<<1|1] = 1;
flag[rt] = 0;
sum[rt<<1]=sum[rt<<1]*lazy_tag[rt];
sum[rt<<1|1]=sum[rt<<1|1]*lazy_tag[rt];
lazy_tag[rt<<1] = lazy_tag[rt<<1]*lazy_tag[rt];
lazy_tag[rt<<1|1] = lazy_tag[rt<<1|1]*lazy_tag[rt];
lazy_tag[rt].E();
} void up_data(int L,int R,int x,int l,int r,int rt)
{
if (L<= l && r <= R)
{
lazy_tag[rt]=lazy_tag[rt]*cur;
sum[rt] = sum[rt]*cur;
flag[rt] = 1;
return;
}
push_down(rt);
int m = (l+r)>>1;
if (L <= m) up_data(L,R,x,lson);
if (m < R) up_data(L,R,x,rson);
push_up(rt);
} MX Q(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R)
return sum[rt];
push_down(rt);
int m = (l+r)>>1;
MX temp1,temp2;
temp1.O(),temp2.O();
if (L <= m) temp1 = Q(L,R,lson);
if (m < R) temp2 = Q(L,R,rson);
temp1 = temp1 + temp2;
return temp1;
} LL query(int l,int r)
{
MX temp = Q(l,r,1,n,1);
temp = temp*v;
return temp.v[1][2];
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
ios::sync_with_stdio(false),cin.tie(0);//scanf,puts,printf not use
cin >> n >> m;
rep1(i,1,n) cin >> a[i];
A.v[1][1] = 0,A.v[1][2] = A.v[2][1] = A.v[2][2] = 1;
v.v[1][1] = v.v[1][2] = v.v[2][1] = 0,v.v[2][2] = 1;
build(1,n,1);
rep1(i,1,m)
{
int type;
cin >> type;
if (type==1)
{
int l,r,x;
cin >> l >> r >> x;
cur = A^x;
up_data(l,r,x,1,n,1);
}
else
{
int l,r;
cin >> l >> r;
cout << query(l,r) << endl;
}
}
return 0;
}

【codeforces 719E】Sasha and Array的更多相关文章

  1. 【24.17%】【codeforces 721D】Maxim and Array

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  2. 【codeforces 754A】Lesha and array splitting

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. 【Codeforces 258B】 Sort the Array

    [题目链接] http://codeforces.com/contest/451/problem/B [算法] 模拟 在序列中找到一段单调递增的子序列,将这段序列反转,然后判断序列是否变得单调递增,即 ...

  4. codeforces 719E E. Sasha and Array(线段树)

    题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...

  5. 【44.19%】【codeforces 727C】Guess the Array

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  6. 【Codeforces 1042D】Petya and Array

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 把a[i]处理成前缀和 离散化. 枚举i从1..n假设a[i]是区间和的a[r] 显然我们需要找到a[r]-a[l]<t的l的个数 即a ...

  7. 【codeforces 1109B】Sasha and One More Name

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 如果这个回文串的左半部分,字母全是一样的. 那么显然不可能再分出来了,因为不管怎么分怎么排列,最后肯定都只能和原串一样. 所以无解 其他情况下 ...

  8. 【Codeforces 1114B】Yet Another Array Partitioning Task

    [链接] 我是链接,点我呀:) [题意] 让你把数组分成k个连续的部分 使得每个部分最大的m个数字的和最大 [题解] 把原数组降序排序 然后选取前m*k个数字打标记 然后对于原数组 一直贪心地取 直到 ...

  9. 【Codeforces 1109C 】Sasha and a Patient Friend

    Codeforces 1109 C 题意:现在有个碗,每时每刻其中的水量都会加一个整数(可以为负). 给\(n\)个询问,询问有\(3\)种类型: \(1\ t\ s\):将从第\(t\)秒开始水量增 ...

随机推荐

  1. POJ1789&amp;ZOJ2158--Truck History【最小生成树变形】

    链接:http://poj.org/problem?id=1789 题意:卡车公司有悠久的历史,它的每一种卡车都有一个唯一的字符串来表示,长度为7,它的全部卡车(除了第一辆)都是由曾经的卡车派生出来的 ...

  2. POJ 1442 Black Box(优先队列)

    题目地址:POJ 1442 这题是用了两个优先队列,当中一个是较大优先.还有一个是较小优先. 让较大优先的队列保持k个.每次输出较大优先队列的队头. 每次取出一个数之后,都要先进行推断,假设这个数比較 ...

  3. JavaScript高级特性之原型

    JavaScript的原型 原型prototype属性仅仅适用于函数对象(这里的函数对象是自己为了理解更好定义的,普通对象是没有原型属性的) 1.研究函数原型: <script type=&qu ...

  4. session 的工作原理

    session.cookie_domain session.cookie_path session.name session.save_path session.use_cokies session_ ...

  5. ProjectRuler 算法练习之 位数组成字符串同样的整数

    Problem :It can be seen that the number, 125874, and its double, 251748, contain exactly the same di ...

  6. Git 工具 - 子模块

    子模块 有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目. 也许是第三方库,或者你独立开发的,用于多个父项目的库. 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使 ...

  7. 3-3 第三天 Promise 如何使用

    回调的方式来处理异步,目的是要保证一个执行顺序,先完成什么再去完成什么,它们的作用其实是相同的,显然回调更容易来书写,但是它难以维护,很容易遗漏错误处理代码而且无法使用return语句来返回这个值. ...

  8. etcd创建集群并增加节点

    下载安装 从这下载https://github.com/coreos/etcd/releases/download/v3.3.2/etcd-v3.3.2-linux-amd64.tar.gz tar ...

  9. jquery事件重复绑定的几种解决方法

    防止事件重复绑定共有4种方法: bind().unbind()方法 live().die()方法 off().on()方法 one()方法 一.bind().unbind()方法 bind();绑定事 ...

  10. BZOJ 3992 DP+NTT+快速幂

    思路: 普通的DP很好想吧 f[i][j]+=f[i-1][j*s[k]]  前i个数  mod m=j 的个数 m是质数  模数是质数  这就很有趣了 那么我们就求出来原根  所有的数都取指数 搞出 ...