题目链接

分析:矩阵快速幂+线段树 斐波那契数列的计算是矩阵快速幂的模板题,这个也没什么很多好解释的,学了矩阵快速幂应该就知道的东西= =这道题比较巧妙的在于需要用线段树来维护矩阵,达到快速查询区间斐波那契数列和的目的。这道题极为卡常数,我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的更多相关文章

  1. 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 ...

  2. 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 ...

  3. Codeforces Round #373 (Div. 1)

    Codeforces Round #373 (Div. 1) A. Efim and Strange Grade 题意 给一个长为\(n(n \le 2 \times 10^5)\)的小数,每次可以选 ...

  4. Codeforces Round #373 (Div. 2)A B

    Codeforces Round #373 (Div. 2) A. Vitya in the Countryside 这回做的好差啊,a想不到被hack的数据,b又没有想到正确的思维 = = [题目链 ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. Codeforces Round #373 (Div. 2)

    A,B,C傻逼题,就不说了. E题: #include <iostream> #include <cstdio> #include <cstring> #inclu ...

随机推荐

  1. 【转载】免费台北.edu教育邮箱及Office 365 Education申请

    免费的邮箱非常多,但是免费的.edu教育邮箱却很少有.记得上次不少人寻找.edu教育邮箱还是因为国外一家VPS商家推出的专门针对学生的优惠包,使用.edu教育邮箱就可以获得50美元的优惠,真的很划算. ...

  2. [OSG]OpenSceneGraph FAQ 以及OSG资源

    1.地球背面的一个点,计算它在屏幕上的坐标,能得到吗? 不是被挡住了吗? 答:计算一个空间点的屏幕坐标,使用osgAPEx::GetScreenPosition函数.当空间点处于相机视空间内(不管它是 ...

  3. Mysql查询重复记录

    第一步 使用group by 和 having cout 查找重复字段 SELECT t1.`order_book_id` FROM `quant_stock_info` t1 GROUP BY t1 ...

  4. 【转】Android Https服务器端和客户端简单实例

    转载地址:http://blog.csdn.net/gf771115/article/details/7827233 AndroidHttps服务器端和客户端简单实例 工具介绍 Eclipse3.7 ...

  5. ABAP代码编辑器设置--界线

    ABAP编辑器每行允许的最大字符数: Utilities->Settings打开选项卡: 勾选:Downward-Compat.line Length(72) 设置后看到的效果: 设置步骤:

  6. Intellij jrebel 热部署

    Intellij 14破解下载 注册机 即可进行破解.JRebel安装下载IntelliJ IDEA的 JRebel插件: jr-ide-idea-6.2.0-idea-13-14.zip. 打开In ...

  7. python-正则表达式基础

    转载作者:AstralWind 1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可 ...

  8. IOS 断点下载

    // // ViewController.m // UI4_断点下载 // // Created by qianfeng on 15/8/19. // Copyright (c) 2015年 ZBC. ...

  9. python之路2(基础详解)

    python一切都是对象: 列子:

  10. HTLM5第一天的内容

    网页的本质就是超级文本标记语言:Hyper Text Markup Language 网页的组成:结构(HTML)  样式(CSS)  行为(JavaScript) 万维网联盟:W3C:World W ...