题目链接 http://codeforces.com/problemset/problem/719/E

解题思路

矩阵上的线段树。

因为矩阵有分配律(A+B)C = AC + BC,所以计算总和时直接把增量矩阵乘上去就行了。用矩阵快速幂。

fib的计算尽量拉到主函数计算。

代码

#include<stdio.h>
#include<string.h>#define MAX_SIZE 100010
const int MOD_NUM = 1e9 + 7;
typedef long long ll;
struct mat {mat() {}mat(int a, int b, int c, int d){ ans[0][0] = a; ans[0][1] = b; ans[1][0] = c; ans[1][1] = d; } int ans[2][2];bool JudgeOne(){for(int i=0; i<2; i++)for(int j=0; j<2; j++)if(i == j && ans[i][j] != 1 || i != j && ans[i][j] != 0)return false;return true;}void SetOne(){for(int i=0; i<2; i++)for(int j=0; j<2; j++)ans[i][j] = (i == j) ? 1 : 0;}mat operator *(const mat &b)const{mat c(0,0,0,0);for(int k=0; k<2; k++)for(int i=0; i<2; i++)for(int j=0; j<2; j++)c.ans[i][j] = (c.ans[i][j] + (ll)ans[i][k] * b.ans[k][j]) % MOD_NUM;return c;}mat operator +(const mat &b)const{mat c;for(int i=0; i<2; i++)for(int j=0; j<2; j++)c.ans[i][j] = (ans[i][j] + b.ans[i][j]) % MOD_NUM; return c;}
};
struct node {mat sum; mat tempt;
}tree[4*MAX_SIZE];
mat a[MAX_SIZE];
mat temp;
mat cal_fib(int x)
{mat c; mat t(0,1,1,1);c.SetOne();while(x) {if(x & 1) c = c * t;t = t * t;x  = x >> 1;}return c;
}
void build(int l, int r, int root)
{tree[root].tempt.SetOne();if(l == r) {tree[root].sum = a[l];return ;}int mid = (l + r) / 2;build(l, mid, root*2);build(mid+1, r, root*2+1);tree[root].sum = tree[root*2].sum + tree[root*2+1].sum;
}
void down(int root)
{tree[root*2].sum = tree[root*2].sum * tree[root].tempt;tree[root*2].tempt = tree[root*2].tempt * tree[root].tempt;tree[root*2+1].sum = tree[root*2+1].sum * tree[root].tempt;tree[root*2+1].tempt = tree[root*2+1].tempt * tree[root].tempt;tree[root].tempt.SetOne();
}
void query_1(int l, int r, int L, int R, int root, mat value)
{if(L == l && r == R) {tree[root].tempt = tree[root].tempt * value;tree[root].sum = tree[root].sum * value;return ;}if(!tree[root].tempt.JudgeOne()) {down(root);}int mid = (L + R) / 2;if(r <= mid) query_1(l, r, L, mid, root*2, value);else if(l > mid) query_1(l, r, mid+1, R, root*2+1, value);else {query_1(l, mid, L, mid, root*2, value);query_1(mid+1, r, mid+1, R, root*2+1, value);}tree[root].sum = tree[root*2].sum + tree[root*2+1].sum;
}
int query_2(int l, int r, int L, int R, int root)
{if(L == l && r == R) {return tree[root].sum.ans[0][1];}if(!tree[root].tempt.JudgeOne()) {down(root);}int ret = 0;int mid = (L + R) / 2;if(r <= mid) ret = query_2(l, r, L, mid, root*2);else if(l > mid) ret = query_2(l, r, mid+1, R, root*2+1);else {ret = query_2(l, mid, L, mid, root*2) + query_2(mid+1, r, mid+1, R, root*2+1) % MOD_NUM;}return ret % MOD_NUM;
}
int main()
{int n, m, d;scanf("%d%d", &n, &m);for(int i=1; i<=n; i++) {mat base(0, 1, 1, 1);scanf("%d", &d); a[i] = cal_fib(d);}build(1, n, 1);for(int i=0; i<m; i++) {int type, l, r, x;scanf("%d", &type);if(type == 1) {mat base(0, 1, 1, 1);scanf("%d%d%d", &l, &r, &x);temp = cal_fib(x);query_1(l, r, 1, n, 1, temp);}else {scanf("%d%d", &l, &r);printf("%d\n", query_2(l, r, 1, n, 1));}}return 0;
}

转载于:https://www.cnblogs.com/ZengWangli/p/5933256.html

cf-Sasha and Array相关推荐

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

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

  2. cf D. Powerful array 莫队算法

    D. Powerful array 题意:给定一个序列>>每次查询一个区间>>查询该区间内 出现过的数字*出现的次数的平方 的和 思路:学习莫队的第一题或者说小z的袜子是第一题 ...

  3. 【题解】 CF718C Sasha and Array

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

  4. [CF718C] Sasha and Array

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

  5. [动态dp]线段树维护转移矩阵

    背景:czy上课讲了新知识,从未见到过,总结一下. 所谓动态dp,是在动态规划的基础上,需要维护一些修改操作的算法. 这类题目分为如下三个步骤:(都是对于常系数齐次递推问题) 1先不考虑修改,不考虑区 ...

  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. CF刷题(03)——难度2100~2400

    这个博客记录2100到2400共17个题 2100 1.B. Maximum Value 题意:You are given a sequence a consisting of nnn integer ...

  8. linux 粘贴内容命令行,Linux下命令行中的复制和粘贴

    PHP面向对象常见的关键字和魔术方法 在PHP5的面向对象程序设计中提供了一些常见的关键字,用来修饰类.成员属性或成员方法,使他们具有特定的功能,例如final.static.const等关键字.还有 ...

  9. c语言定义int 输出4386,C语言 · 矩阵乘法

    问题描述 输入两个矩阵,分别是m*s,s*n大小.输出两个矩阵相乘的结果. 输入格式 第一行,空格隔开的三个正整数m,s,n(均不超过200). 接下来m行,每行s个空格隔开的整数,表示矩阵A(i,j ...

  10. Presto数组函数

    下标运算符:[] 该[]运算符用于访问数组的元素,并从 1 开始索引: SELECT my_array[1] AS first_element 连接运算符: || 该||运算符用于将数组与数组或相同类 ...

最新文章

  1. [cocos2d-x]cocos2d和cocos2d-x的一些通用性
  2. realloc函数引发的慘案
  3. 软件工程结对作业02
  4. Delphi应用程序的调试(四)The Debug Inspector
  5. gitignore重要技巧
  6. Go的string/int/int64转化
  7. Ubuntu 12.10使用apt安装Oracle/Sun JDK
  8. 论文浅尝 | 基于置信度的知识图谱表示学习框架
  9. ScheduleJobFactory
  10. C4D优质电商背景素材|分分钟搞定设计稿
  11. 跨境商家为什么要建自己的独立站?
  12. jooq生成records_Java 14 Records类
  13. Hide()方法不生效
  14. base——JavaSEJavaEEJavaME的区别【Java中常用的包结构】
  15. 使用cloudFlare实现动态DNS解析
  16. angular复用路由组件_Angular Router的组件路由简介
  17. 英语掌握的程度,与Python有没有关系
  18. android中一些特殊字符(如:←↑→↓等箭头符号)的Unicode码值
  19. 光量子领域新突破:有望打造芯片工厂!
  20. Dubbo3.0系列(2)- Dubbo3.0核心概念与架构

热门文章

  1. Windows Mobile 5.0 设备的目录变化
  2. 比特币核心概念及算法
  3. 数据库更行通知_哪个更好? 数据驱动还是数据通知?
  4. 计算机组原理ppt,计算机组原理第三章.ppt
  5. springMVC出现HTTP Status 405 - Request method 'GET' not supported错误的解决方法
  6. 通过yum安装配置lamp
  7. 如何成功地在亚洲植入敏捷和DevOps
  8. IOS UITabBarViewController 修改背景颜色
  9. tomcat中server.xml文件详解
  10. java学习笔记11--Annotation