\(Description:\)

设计一个数据结构,支持区间加,区间求斐波那契和,比如求\(\sum_{i=l}^{r} f(a_i)\)

\(Sample\) \(Input:\)

5 4
1 1 2 1 1
2 1 5
1 2 4 2
2 2 4
2 1 5

\(Sample\) \(Output:\)

5
7
9

考虑想段树上每个节点维护一个矩阵,因为矩阵满足结合律:
\(a*c+b*c=(a+b)*c\)

但由于幂运算不满足结合律,那么就不能直接在线段树的懒标记里面存幂次,要存一个矩阵,每次修改的时候乘一下。

但还有一个要考虑的:

如果普通斐波那契的话,矩阵快速幂的时候是原矩阵是\(f[n-1],f[n-2]=>1,1\),但这里面如果原矩阵为这个就没办法询问到\(f[1]\)

其他的话只要注意下传懒标记之后吧懒标记变为单位矩阵就行了。

哦,还有要开long long

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
const int N=1e5,p=1e9+7;
int a[N+3];
struct matrix {int a[3][3];inline void set  (int x) { for(int i=1;i<=x;++i) a[i][i]=1;}inline void clear() { memset(a,0,sizeof(a));}inline bool operator != (const matrix &nt) const {for(int i=1;i<=n;++i) for(int j=1;j<=n;++j)}inline matrix operator  + (const matrix &nt) const {matrix tmp;tmp.clear();for(int i=1;i<=2;++i) for(int j=1;j<=2;++j)tmp.a[i][j]=(a[i][j]+nt.a[i][j])%p;return tmp;}inline matrix operator  * (const matrix &nt) const {matrix tmp;tmp.clear();for(int i=1;i<=2;++i) for(int j=1;j<=2;++j) for(int k=1;k<=2;++k)tmp.a[i][j]=(tmp.a[i][j]+a[i][k]*nt.a[k][j]%p)%p;return tmp;}inline matrix write () const {for(int i=1;i<=2;++i){for(int j=1;j<=2;++j) printf("%lld ",a[i][j]);putchar('\n');}return *this;}inline matrix operator *= (const matrix &nt) { return *this=*this*nt;}inline matrix operator += (const matrix &nt) { return *this=*this+nt;}
}ori,oo,ff;
inline matrix power(matrix a,int b){matrix ret;ret.clear();ret.set(2);while(b){if(b&1) ret*=a;a*=a;b>>=1;}return ret;
}struct node {int l,r;matrix v,tag;
}tree[(N<<2)+2];
inline int lc(int k){return k<<1;}
inline int rc(int k){return k<<1|1;}
inline void push_up(int k){ tree[k].v=tree[lc(k)].v+tree[rc(k)].v;}
inline void push_down(int k){tree[lc(k)].v*=tree[k].tag;tree[rc(k)].v*=tree[k].tag;tree[lc(k)].tag*=tree[k].tag;tree[rc(k)].tag*=tree[k].tag;tree[k].tag.clear();tree[k].tag.set(2);
}
inline void build(int k,int l,int r){tree[k].l=l;tree[k].r=r;tree[k].tag.set(2);if(l==r){tree[k].v=oo*power(ori,a[l]);return;}int mid=(l+r)>>1;build(lc(k),l,mid);build(rc(k),mid+1,r);push_up(k);
}
inline void update(int k,int l,int r,matrix x){if(l<=tree[k].l && tree[k].r<=r){tree[k].v*=x;tree[k].tag*=x;return;}int mid=(tree[k].l+tree[k].r)>>1;push_down(k);if(l<=mid) update(lc(k),l,r,x);if(r>mid)  update(rc(k),l,r,x);push_up(k);
}
inline int query(int k,int l,int r){if(l<=tree[k].l && tree[k].r<=r) return tree[k].v.a[1][1]%p;int mid=(tree[k].l+tree[k].r)>>1;push_down(k);int ret=0;if(l<=mid) ret=(ret+query(lc(k),l,r))%p;if(r>mid)  ret=(ret+query(rc(k),l,r))%p;return ret;
}
signed main(){freopen("1.out","w",stdout);ff.set(2);ori.a[1][1]=1;ori.a[1][2]=1;ori.a[2][1]=1;ori.a[2][2]=0;oo.a[1][1]=0;oo.a[1][2]=1;scanf("%lld%lld",&n,&m);for(int i=1;i<=n;++i) scanf("%lld",&a[i]);build(1,1,n);for(int i=1;i<=m;++i){int opt=0;scanf("%lld",&opt);if(opt==1){int l=0,r=0,x=0;scanf("%lld%lld%lld",&l,&r,&x);update(1,l,r,power(ori,x));}if(opt==2){int l=0,r=0;scanf("%lld%lld",&l,&r);printf("%lld\n",query(1,l,r));}}return 0;
}

转载于:https://www.cnblogs.com/JCNL666/p/10669796.html

【题解】 CF718C Sasha and Array相关推荐

  1. [CF718C] Sasha and Array

    Description 给定一个数列,维护两种操作 操作 \(1\),将区间 \([l,r]\) 的数字统一加 \(x\). 操作 \(2\),求 \(\sum \limits_{i=l}^r f(v ...

  2. CF719E. Sasha and Array [线段树维护矩阵]

    CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...

  3. Leetcode PHP题解--D16 922. Sort Array By Parity II

    2019独角兽企业重金招聘Python工程师标准>>> 922. Sort Array By Parity II 题目链接 922. Sort Array By Parity II ...

  4. Leetcode PHP题解--D7 905. Sort Array By Parity

    2019独角兽企业重金招聘Python工程师标准>>> 905. Sort Array By Parity 题目链接 905. Sort Array By Parity 题目分析 这 ...

  5. 【Codeforces Round #767 (Div. 2)】 C. Meximum Array 题解

    [Codeforces Round #767 (Div. 2) ]C. Meximum Array 题解 1629C: Meximum Array 题解 [Codeforces Round #767 ...

  6. 【codeforces 718 CD】C. Sasha and ArrayD. Andrew and Chemistry

    C. Sasha and Array 题目大意&题目链接: http://codeforces.com/problemset/problem/718/C 长度为n的正整数数列,有m次操作,$o ...

  7. Codeforces Round #521 (Div.3)题解

    A过水,不讲 题解 CF1077B [Disturbed People] 这题就是个显而易见的贪心可是我考场上差点没想出来 显然把一户被打扰的人家的右边人家的灯关掉肯定比把左边的灯关掉 从左到右扫一遍 ...

  8. asp子窗口读取父窗口数据_算法与数据结构基础 - 数组(Array)

    数组基础 数组是最基础的数据结构,特点是O(1)时间读取任意下标元素,经常应用于排序(Sort).双指针(Two Pointers).二分查找(Binary Search).动态规划(DP)等算法.顺 ...

  9. Codeforces Round #636 (Div. 3) 题解

    A. Candies 查看题解 数学 B. Balanced Array 查看题解 数学 C. Alternating Subsequence 查看题解 贪心 D. Constant Palindro ...

最新文章

  1. 行转列 oracle nvl,oracle 行转列 decode
  2. 一个多线程死锁案例,如何避免及解决死锁问题?
  3. Daily Scrum - 11/24
  4. 这个搞定系统监控的妙招,不来学可惜了
  5. 华为android怎样隐藏软件,华为怎么打开隐藏应用功能
  6. mysql 备份脚本
  7. ssm框架sql换成MySQL_搭建ssm框架,可实现登录和数据展示以及增删改查
  8. Flume在企业大数据仓库架构中位置及功能
  9. Android 10系统新特性解读
  10. 单循环赛制php,告别东西部分组LPL实行常规赛单循环赛制
  11. cisco链路聚合配置
  12. 非平衡电桥电阻计算_用非平衡电桥测量电阻
  13. 微信小程序开发之动图小游戏是实现(代码篇)
  14. Android开发:指南针(基于手机传感器)
  15. 【手机跳板 多款软件测试】图文演示!
  16. FineBI 无法将聚合和非聚合参数混用(或条件求和)
  17. order by(排序查询结果)和LIMT
  18. java 面试知识点笔记(七)多线程与并发 上篇
  19. scratch3.0自定义logo
  20. MapGuide API

热门文章

  1. 神经网络中的「注意力」是什么?怎么用?
  2. 当上 CTO 才发现:程序员时常犯的 4 个错误有多可怕!
  3. 97.16% 的加班率,给你 3 倍工资:你愿意去大厂吗?
  4. 尴尬!因软件 Bug ,美国数百名囚犯释放后无法出狱
  5. NodeJS + PhantomJS 前端自动化资源监控
  6. Spring Boot特性
  7. django_2.0_请求处理
  8. p2148 [SDOI2009]ED
  9. 小白学python系列-(3)基础数量类型
  10. 向大家推荐一个C/C++通用Makefile