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 ...
随机推荐
- es搜索引擎
1.es简介 2.es优缺点 3.es使用 4.es可以解决的问题 5.es举例 6.es执行结果截图 7.es数据增量方案 8.使用es搜索 一.es简介 es是一个是一个实时的分布式搜索和分析引擎 ...
- java ide 导出可运行jar包
常常会用到写个jar搬到其他地方运行的情况,这里做个笔记记录下如何利用eclipse或者idea导出jar. 导出jar包最好的方式个人认为是把依赖的包都打包进目标jar,这样一个jar可以很happ ...
- CSS3自定义滚动条样式 -webkit-scrollbar
今天写项目碰上需要改滚动条效果,我的第一反应是,需要用js写滚动条,顿时头大,上网搜了一下,原来css3就可以修改滚动条样式了,非常好啊,下面分享原文地址:http://www.xuanfengge. ...
- xcopy /r /y "$(TargetPath)" "$(ProjectDir)"..\CMSAdmin\DLL\
作用:1.所有都生成这里容易管理 2.tfs获取的时候不会有出问题 3.如果都是引用项目 会存在先后顺序 也会导致生成代码的时候出问题
- sql 语句纵表变横表
现把转换方法列举如下: 1.纵表转横表: 纵表结构 TableA Name Course Grade 张三 语文 75 张三 数学 80 张三 英语 90 李四 语文 95 李四 数学 55 横表结构 ...
- laravel框架总结(十一) -- 集合
创建集合: collect 辅助函数会利用传入的数组生成一个新的 Illuminate\Support\Collection 实例. $collection = collect([1, 2, 3] ...
- GOLANG 基本数据类型 整型
基本数据类型-整型 种类 有符号(负号) int8 int16 int32 int64 无符号(无符号) uint8 uint16 uint32 uint64 架构特定(取决于系统位 ...
- LayoutControl让一个控件占据多行或者多列
拖动一个layoutcontrol到form上之后,会自动附带一个layoutgroup 设置layoutgroup的layoutmode为table 设置layoutgroup的OptionsTab ...
- phpcms 中路径问题
<table width="100%" border="0" cellspacing="0" cellpadding="0& ...
- Linux就该这么学
第三章:Vim编辑器与Shell脚本 Vim文本编辑器 在Linux系统中配置应用服务,实际上就是在修改它的配置文件. 在热门的Linux操作系统中都会默认安装一款超好用的文本编辑器--"v ...