【题目链接】: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. linux 线程切换效率与进程切换效率相差究竟有多大?

    Author:DriverMonkey Mail:bookworepeng@Hotmail.com Phone:13410905075 QQ:196568501 Are Linux threads t ...

  2. 17229 Lry,你除了2还是2

    17229 Lry,你除了2还是2 时间限制:1000MS  内存限制:65535K提交次数:282 通过次数:46 收入:22 题型: 编程题   语言: G++;GCC Description L ...

  3. S 禁止F12和右键操作控制台,兼容各浏览器

    document.oncontextmenu = function () { return false; };         document.onkeydown = function () {   ...

  4. 报错configure:error: no acceptable C compiler found in $PATH。。

    报错configure:error: no acceptable C compiler found in $PATH.. 查看日志: 出错原因:新安装的linux系统,没有gcc库 解决方案:使用yu ...

  5. Windows 7下Git SSH 创建Key【待解决?】

    1.在桌面右键,git bash here 2.检查本机是否有ssh key设置 $ cd ~/.ssh 或cd .ssh 如果没有则提示: No such file or directory:此时需 ...

  6. Fitnesse Slim的使用

    官网上的使用说明:http://www.fitnesse.org/FitNesse.UserGuide.WritingAcceptanceTests.Slim 本文主要介绍Slim常用的几种表格,更多 ...

  7. 《深入浅出 Java Concurrency》——原子操作

    part1 从AtomicInteger開始 从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包.而Queue.非常多情况下使用到了Atomic操作.因此首 ...

  8. phpfpm的配置

    1.php中fastcgi和php-fpm是什么东西 最近在研究和学习PHP的性能方面的知识,看到了factcgi以及php-fpm,发现我对他们是少之又少的理解,可以说几乎是一无所知,想想还是蛮可怕 ...

  9. luogu2766 最长不下降子序列问题 DP 网络流

    题目大意:给定正整数序列x1,...,xn .(1)计算其最长不下降子序列的长度s.(不一定是否连续)(2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列.(序列内每一个元素不可重复)(3) ...

  10. FastDFS介绍(非原创)

    文章大纲 一.FastDFS介绍二.FastDFS安装与启动(Linux系统)三.Java客户端上传图片四.参考文章   一.FastDFS介绍 1. 什么是FastDFS FastDFS是用C语言编 ...