题目大意

给你一个序列\(a_1, a_2, ..., a_n\). 我们令函数\(f(n)\)表示斐波那契数列第\(n\)项的值. 总共\(m\)个操作, 分为以下两种:

  • 将\(x \in [L, R]\)中的所有\(a_x\)加上一个数\(k\);
  • 询问\(\sum_{x \in [L, R]}f(a_x)\)

\(n \le 10^5\)

\(m \le 10^5\)

Solution

我们靠考虑斐波那契数列的转移矩阵:

\[[f_{a + b - 1} \ f_{a + b}] = [f_{a - 1} \ f_a] \left[ \begin{array}{} 0 \ 1 \\ 1 \ 1 \end{array} \right]^b
\]

同时我们发现若干个斐波那契数之和也满足这个关系.

因此我们用线段树维护每个区间的\(\sum_{L \le i \le R} f(a_i)\)以及\(\sum_{L \le i \le R} f(a_{i - 1})\), 区间修改查询即可.

注意作为常数优化, 我们要预处理出转移矩阵的\(2^n\)次幂. 否则会TLE.

话说拿这种小技巧, 把正确复杂度的代码卡到30分, 是不是也太丧心病狂了!!!

#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib> namespace Zeonfai
{
inline long long getInt()
{
long long a = 0, sgn = 1; char c;
while(! isdigit(c = getchar())) if(c == '0') sgn *= -1;
while(isdigit(c)) a = a * 10 + c - '0', c = getchar();
return a * sgn;
}
}
const long long N = (long long)1e5, MOD = (long long)1e9 + 7;
long long n;
struct matrix
{
long long a[2][2];
inline matrix operator *(const matrix &A)
{
matrix res; memset(res.a, 0, sizeof(res.a));
for(long long i = 0; i < 2; ++ i) for(long long j = 0; j < 2; ++ j) for(long long k = 0; k < 2; ++ k)
res.a[i][j] = (res.a[i][j] + (long long)a[i][k] * A.a[k][j] % MOD) % MOD;
return res;
}
}trans, ptt[64];
inline matrix power(long long x)
{
matrix res; memset(res.a, 0, sizeof(res.a)); res.a[0][0] = res.a[1][1] = 1;
if(x < 0) return res;
long long p = 0;
for(; x; x >>= 1, ++ p)
if(x & 1) res = res * ptt[p];
return res;
}
struct segmentTree
{
struct node
{
long long cur, lst;
long long tg; // 注意到tg的值叠加后可能超过Long long
inline node() {cur = 0; lst = 1; tg = 0;}
}nd[N << 2];
inline void pushDown(long long _u)
{
long long x = nd[_u].tg; long long u = _u << 1;
matrix res = power(x);
long long a = ((long long)nd[u].lst * res.a[0][0] % MOD + (long long)nd[u].cur * res.a[1][0] % MOD) % MOD,
b = ((long long)nd[u].lst * res.a[0][1] % MOD + (long long)nd[u].cur * res.a[1][1] % MOD) % MOD;
nd[u].lst = a; nd[u].cur = b;
nd[u].tg += x;
u = _u << 1 | 1;
a = ((long long)nd[u].lst * res.a[0][0] % MOD + (long long)nd[u].cur * res.a[1][0] % MOD) % MOD;
b = ((long long)nd[u].lst * res.a[0][1] % MOD + (long long)nd[u].cur * res.a[1][1] % MOD) % MOD;
nd[u].lst = a; nd[u].cur = b;
nd[u].tg += x;
nd[_u].tg = 0;
}
void modify(long long u, long long curL, long long curR, long long L, long long R, long long x)
{
if(curL >= L && curR <= R)
{
nd[u].tg += x;
matrix res = power(x);
long long a = ((long long)nd[u].lst * res.a[0][0] % MOD + (long long)nd[u].cur * res.a[1][0] % MOD) % MOD,
b = ((long long)nd[u].lst * res.a[0][1] % MOD + (long long)nd[u].cur * res.a[1][1] % MOD) % MOD;
nd[u].lst = a; nd[u].cur = b;
return;
}
pushDown(u);
long long mid = curL + curR >> 1;
if(L <= mid) modify(u << 1, curL, mid, L, R, x);
if(R > mid) modify(u << 1 | 1, mid + 1, curR, L, R, x);
nd[u].cur = (nd[u << 1].cur + nd[u << 1 | 1].cur) % MOD;
nd[u].lst = (nd[u << 1].lst + nd[u << 1 | 1].lst) % MOD;
}
inline void modify(long long L, long long R, long long x) {modify(1, 1, n, L, R, x);}
long long query(long long u, long long curL, long long curR, long long L, long long R)
{
if(curL >= L && curR <= R) return nd[u].cur;
pushDown(u);
long long mid = curL + curR >> 1, res = 0;
if(L <= mid) res = query(u << 1, curL, mid, L, R);
if(R > mid) res = (res + query(u << 1 | 1, mid + 1, curR, L, R)) % MOD;
return res;
}
inline long long query(long long L, long long R) {return query(1, 1, n, L, R);}
}seg;
int main()
{ #ifndef ONLINE_JUDGE freopen("fibonacci.in", "r", stdin);
freopen("_fibonacci.out", "w", stdout); #endif using namespace Zeonfai;
trans.a[0][0] = 0; trans.a[0][1] = trans.a[1][0] = trans.a[1][1] = 1;
ptt[0] = trans;
for(long long i = 1; i < 64; ++ i) ptt[i] = ptt[i - 1] * ptt[i - 1];
n = getInt(); long long m = getInt();
for(long long i = 1; i <= n; ++ i) seg.modify(i, i, getInt());
for(long long i = 0; i < m; ++ i)
{
long long opt = getInt(), L = getInt(), R = getInt();
if(opt == 1)
{
long long x = getInt();
seg.modify(L, R, x);
}
else if(opt == 2) printf("%d\n", seg.query(L, R));
}
}

noip2017集训测试赛(四)Problem A: fibonacci的更多相关文章

  1. noip2017集训测试赛(三) Problem B: mex [补档]

    Description 给你一个无限长的数组,初始的时候都为0,有3种操作: 操作1是把给定区间[l,r][l,r] 设为1, 操作2是把给定区间[l,r][l,r] 设为0, 操作3把给定区间[l, ...

  2. noip2017集训测试赛(十一)Problem C: 循环移位

    题面 Description 给定一个字符串 ss .现在问你有多少个本质不同的 ss 的子串 t=t1t2⋯tm(m>0)t=t1t2⋯tm(m>0) 使得将 tt 循环左移一位后变成的 ...

  3. noip2017集训测试赛(六)Problem A: 炮艇大赛之正式赛

    题目描述 给定一个长度为\(L \le 10^9\)的环形赛道, \(n \le 10^5\)个人在上面赛艇. 每个人的速度都不相同, 假如为正则顺时针走, 否则逆时针走. 当两个人相遇时, 他们就会 ...

  4. noip2017集训测试赛(三)Problem C: MST

    题面 Description 给定一个n个点m条边的连通图,保证没有自环和重边.对于每条边求出,在其他边权值不变的情况下,它能取的最大权值,使得这条边在连通图的所有最小生成树上.假如最大权值为无限大, ...

  5. noip2019集训测试赛(二十一)Problem B: 红蓝树

    noip2019集训测试赛(二十一)Problem B: 红蓝树 Description 有一棵N个点,顶点标号为1到N的树.N−1条边中的第i条边连接顶点ai和bi.每条边在初始时被染成蓝色.高桥君 ...

  6. 2016集训测试赛(二十四)Problem B: Prz

    Solution 这道题有两个关键点: 如何找到以原串某一个位置为结尾的某个子序列的最晚出现位置 如何找到原串中某个位置之前的所有数字的最晚出现位置中的最大值 第一个关键点: 我们注意到每个数字在\( ...

  7. 2016集训测试赛(二十四)Problem C: 棋盘控制

    Solution 场上的想法(显然是错的)是这样的: 我们假设棋子是一个一个地放置的, 考虑在放置棋子的过程中可能出现哪些状态. 我们令有序整数对\((i, j)\)表示总共控制了\(i\)行\(j\ ...

  8. 2016北京集训测试赛(十四)Problem B: 股神小D

    Solution 正解是一个\(\log\)的link-cut tree. 将一条边拆成两个事件, 按照事件排序, link-cut tree维护联通块大小即可. link-cut tree维护子树大 ...

  9. 2016北京集训测试赛(十四)Problem A: 股神小L

    Solution 考虑怎么卖最赚钱: 肯定是只卖不买啊(笑) 虽然说上面的想法很扯淡, 但它确实能给我们提供一种思路, 我们能不买就不买; 要买的时候就买最便宜的. 我们用一个优先队列来维护股票的价格 ...

随机推荐

  1. 1010: [HNOI2008]玩具装箱toy(斜率优化)

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 12280  Solved: 5277[Submit][S ...

  2. U10783 名字被和谐了

    U10783 名字被和谐了 题目背景 众所周知,我们称g是a的约数,当且仅当g是正数且a mod g = 0. 众所周知,若g既是a的约数也是b的约数,我们称g是a.b的一个公约数. 众所周知,a.b ...

  3. np.newaxis()用法

    这个是liaspace函数 这个是np.newaxis的用法,增加维度,写一个表示增加一维,两个表示增加2维2位置的:号是对a的取值范围,如果把np.newaxis作为第一个参数是对行增加维度,作为第 ...

  4. ajax提交表单,支持文件上传

    当我们提交表单但是又不想要刷新页面的时候就可以考虑使用ajax来实现提交功能,但是这有个局限就是当有文件上传的时候是行不通的,下面借助于jquery.form可以很方便满足我们的需求.   1.表单写 ...

  5. jmter+ANT+jekins之配置文件简单优化(build.xml)

    <?xml version="1.0" encoding="utf-8"?> <project name="ant-jmeter-t ...

  6. Python-S9-Day116——Flask框架相关

    01 内容回顾 02 Flask框架:路由和视图(一) 03 Flask框架:路由和视图(二) 04 Flask框架:路由和视图(三) 05 Flask框架:路由和视图(四) 06 Flask框架:s ...

  7. DFS排列组合问题

    这四个使用DFS来求解所有组合和排列的例子很有代表性,这里做一个总结: 1.不带重复元素的子集问题 public ArrayList<ArrayList<Integer>> s ...

  8. idea使用maven逆向mybitis的文件

    引用自 http://blog.csdn.net/for_my_life/article/details/51228098 本文介绍一下用Maven工具如何生成Mybatis的代码及映射的文件. 一. ...

  9. js日期处理

    Js获取当前日期时间及其它操作 var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整 ...

  10. iis特殊后缀文件下载404

    项目中有特殊类型的文件上传到服务器,下载的时候报404,下载不下来.如后缀名为qwwq这种类型. 因为遇到过这种情况,以前都是配置mime类型好的,但是这次没有找到,到底应该配置什么mime类型,一时 ...