Codeforces Round #373 (Div. 2) E. Sasha and Array
分析:矩阵快速幂+线段树 斐波那契数列的计算是矩阵快速幂的模板题,这个也没什么很多好解释的,学了矩阵快速幂应该就知道的东西= =这道题比较巧妙的在于需要用线段树来维护矩阵,达到快速查询区间斐波那契数列和的目的。这道题极为卡常数,我TLE了不知道多少发,才在赛后过了这道题。
我尝试下来,发现矩阵乘法的写法极为重要,我就是因为用了三层循环来写矩阵乘法导致了悲剧的TLE,一直卡在了第17组数据。我百度了网上别的矩阵快速幂的写法才过了这道题。
还有涨智识的地方是不要随意memset。我原来的矩阵快速幂的模板里面在构造函数的时候会memset元素为0,去掉了这句话,代码快了1s。。。
毕竟萌新还是太嫩,没有很多老司机的经验。。貌似bc87场的第三题也是卡了memset的常数。我也TLE了一发。
/*****************************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define offcin ios::sync_with_stdio(false)
#define sigma_size 26
#define lson l,m,v<<1
#define rson m+1,r,v<<1|1
#define slch v<<1
#define srch v<<1|1
#define sgetmid int m = (l+r)>>1
#define LL long long
#define ull unsigned long long
#define mem(x,v) memset(x,v,sizeof(x))
#define lowbit(x) (x&-x)
#define bits(a) __builtin_popcount(a)
#define mk make_pair
#define pb push_back
#define fi first
#define se second
const int INF = 0x3f3f3f3f;
const LL INFF = 1e18;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-9;
const LL mod = 1e9+7;
const int maxmat = 10;
const ull BASE = 31;
/*****************************************************/
const int maxn = 1e5 + 5;
int a[maxn];
int N, M;
struct Mat {
int N;
LL a[2][2];
Mat (int _n = 2) : N(_n) {
//这里我原来会memset
}
void Debug() {
for (int i = 0; i < N; i ++) {
for (int j = 0; j < N; j ++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}
// Mat operator *(const Mat &rhs) const { //悲剧的三重循环写法
// Mat c(N);
// for (int i = 0; i < N; i ++)
// for (int k = 0; k < N; k ++) {
// if (!a[i][k]) continue;
// for (int j = 0; j < N; j ++)
// c.a[i][j] = (c.a[i][j] + a[i][k] * rhs.a[k][j] % mod) % mod;
// }
// return c;
// }
Mat operator *(const Mat &rhs) const { //同时也能能够避免三重循环需要先memset矩阵的时间复杂度
Mat ret;
ret.a[0][0] = (1ll * a[0][0] * rhs.a[0][0] + 1ll * a[0][1] * rhs.a[1][0]) % mod;
ret.a[1][0] = ret.a[0][1] = (1ll * a[0][0] * rhs.a[0][1] + 1ll * a[0][1] * rhs.a[1][1]) % mod;
ret.a[1][1] = (1ll * a[1][0] * rhs.a[0][1] + 1ll * a[1][1] * rhs.a[1][1]) % mod;
return ret;
}
Mat operator +(const Mat &rhs) const {
Mat c(N);
for (int i = 0; i < N; i ++)
for (int j = 0; j < N; j ++)
c.a[i][j] = (a[i][j] + rhs.a[i][j]) % mod;
return c;
}
};
Mat E(2), F(2);
void init() {
E.a[0][0] = E.a[1][1] = 1;
F.a[0][0] = F.a[0][1] = F.a[1][0] = 1;
}
Mat qpow(Mat A, LL b) {
Mat c = E;
while (b > 0) {
if (b & 1) c = A * c;
b >>= 1;
A = A * A;
}
return c;
}
Mat seg[maxn << 2], col[maxn << 2];
bool add[maxn << 2];
void PushUp(int v) {
seg[v] = seg[slch] + seg[srch];
}
void PushDown(int v, int m) {
if (!add[v]) return;
col[slch] = col[slch] * col[v];
col[srch] = col[srch] * col[v];
seg[slch] = seg[slch] * col[v];
seg[srch] = seg[srch] * col[v];
add[slch] = add[srch] = true;
col[v] = E;
add[v] = false;
}
void build(int l, int r, int v) {
col[v] = E;
if (l == r) {
int k;
scanf("%d", &k);
seg[v] = qpow(F, k - 1);
}
else {
sgetmid;
build(lson);
build(rson);
PushUp(v);
}
}
void update(int L, int R, int x, int l, int r, int v) {
if (L <= l && r <= R) {
Mat temp = qpow(F, x);
seg[v] = seg[v] * temp;
col[v] = col[v] * temp;
add[v] = true;
return;
}
sgetmid;
PushDown(v, r - l + 1);
if (L <= m) update(L, R, x, lson);
if (R > m) update(L, R, x, rson);
PushUp(v);
}
LL query(int L, int R, int l, int r, int v) {
if (L <= l && r <= R) return seg[v].a[0][0];
sgetmid;
PushDown(v, r - l + 1);
LL ans = 0;
if (L <= m) ans = (ans + query(L, R, lson)) % mod;
if (R > m) ans = (ans + query(L, R, rson)) % mod;
return ans;
}
int main(int argc, char const *argv[]) {
cin>>N>>M; init(); mem(add, false);
build(1, N, 1);
while (M --) {
int op;
scanf("%d", &op);
if (op == 1) {
int l, r, x;
scanf("%d%d%d", &l, &r, &x);
update(l, r, x, 1, N, 1);
}
else {
int l, r;
scanf("%d%d", &l, &r);
printf("%I64d\n", query(l, r, 1, N, 1));
}
}
return 0;
}
Codeforces Round #373 (Div. 2) E. Sasha and Array的更多相关文章
- Codeforces Round #373 (Div. 2) E. Sasha and Array 线段树维护矩阵
E. Sasha and Array 题目连接: http://codeforces.com/contest/719/problem/E Description Sasha has an array ...
- Codeforces Round #373 (Div. 2) E. Sasha and Array 矩阵快速幂+线段树
E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Round #373 (Div. 1)
Codeforces Round #373 (Div. 1) A. Efim and Strange Grade 题意 给一个长为\(n(n \le 2 \times 10^5)\)的小数,每次可以选 ...
- Codeforces Round #373 (Div. 2)A B
Codeforces Round #373 (Div. 2) A. Vitya in the Countryside 这回做的好差啊,a想不到被hack的数据,b又没有想到正确的思维 = = [题目链 ...
- Codeforces Round #539 (Div. 2) - D. Sasha and One More Name(思维)
Problem Codeforces Round #539 (Div. 2) - D. Sasha and One More Name Time Limit: 1000 mSec Problem ...
- Codeforces Round #539 (Div. 2) - C. Sasha and a Bit of Relax(思维题)
Problem Codeforces Round #539 (Div. 2) - C. Sasha and a Bit of Relax Time Limit: 2000 mSec Problem ...
- Codeforces Round #373 (Div. 2) C. Efim and Strange Grade 水题
C. Efim and Strange Grade 题目连接: http://codeforces.com/contest/719/problem/C Description Efim just re ...
- Codeforces Round #373 (Div. 2) C. Efim and Strange Grade —— 贪心 + 字符串处理
题目链接:http://codeforces.com/problemset/problem/719/C C. Efim and Strange Grade time limit per test 1 ...
- Codeforces Round #373 (Div. 2)
A,B,C傻逼题,就不说了. E题: #include <iostream> #include <cstdio> #include <cstring> #inclu ...
随机推荐
- postman插件安装教程
第一步: 第二步: 第三步: 这样就可以了. 插件下载链接: http://pan.baidu.com/s/1eRVLMpk 密码: 49vb
- maven项目和普通项目转换
- hdu 4401 Battery
这里只给出代码,感兴趣的可以作以参考: #include <algorithm> #include <cstdio> #include <cstring> #inc ...
- windows10 下访问 virtualbox 虚拟机的linux15.10/16.04 系统 及 用 putty 访问虚拟机的配置
参考: http://www.doc88.com/p-915707596190.html --- 安装samba http://my.oschina.net/u/2260265/blog/405598 ...
- Android first---xml文件生成与解析
一.使用append进行xml生成 Message类属性:private String body; private String date; private String a ...
- 高通平台FastMMI(FFBM模式)简介与进入方法
参考: http://blog.csdn.net/tfslovexizi/article/details/51499979 http://www.voidcn.com/blog/jimbo_lee/a ...
- 统计图表类型选择应用总结&表数据挖掘方法及应用
数据挖掘方法及应用: 图表注意事项 • 信息完整:图表标题.单位.图例.脚注.来源等 • 避免无意义的图表 • 一表反映一个观点 • 只选对的不选复杂的图表 • 标题一句话阐述清楚反映观点 确定对比关 ...
- IOS7 edgesForExtendedLayout
在iOS 7中,苹果引入了一个新的属性,叫做[UIViewController setEdgesForExtendedLayout:],它的默认值为UIRectEdgeAll.当你的容器是naviga ...
- 调度系统任务创建---创建一个JoinTrigger的依赖任务(五)
有时候我们需要创建一个任务,这个任务有多个下游任务,在所有下游任务执行成功后再触发一个join操作. 这种场景可以使用JoinTrigger的触发器来实现. 该场景对应的拓扑结构如下: 该触发器的详细 ...
- rxjava源码中的线程知识
rxjava源码中的线程知识 rx的最精简的总结就是:异步 这里说一下以下的五个类 1.Future2.ConcurrentLinkedQueue3.volatile关键字4.AtomicRefere ...