【题目链接】:http://codeforces.com/contest/719/problem/E

【题意】



给你一个数列,有两种操作1 l r x 给[l,r]区间上的数加上x, 2 l r 询问[l,r]区间fibonacci数列的和(f[l]+f[l+1]+……f[r])

【题解】



斐波那契数列有个矩阵乘法公式

f[n]=

[0 1] ^n× [0 0]
[1 1] [0 1]

最后得到的矩阵A

A[1][2]就是答案;(即第一行第二列)



写个线段树的成段更新;

用懒惰标记记录加上的数字x对应的A^x

维护区间的矩阵和就好;

新增加的A^x不要每次都重新算,不然会T





【Number Of WA】



9



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1e5+100; const int G = 2; //�����С
const int MOD = 1e9 + 7; //�
struct MX
{
LL v[G+1][G+1];
void O() { ms(v, 0); }
void E() { ms(v, 0); for (int i = 1; i <= G; ++i)v[i][i] = 1; }
MX operator * (const MX &b) const
{
MX c; c.O();
for (int k = 1; k <= G; ++k)
{
for (int i = 1; i <= G; ++i) if (v[i][k])
{
for (int j = 1; j <= G; ++j)
{
c.v[i][j] = (c.v[i][j] + (LL)v[i][k] * b.v[k][j]) % MOD;
}
}
}
return c;
}
MX operator + (const MX &b) const
{
MX c; c.O();
for (int i = 1; i <= G; ++i)
{
for (int j = 1; j <= G; ++j)
{
c.v[i][j] = (v[i][j] + b.v[i][j]) % MOD;
}
}
return c;
}
MX operator ^ (LL p) const
{
MX y; y.E();
MX x; memcpy(x.v, v, sizeof(v));
while (p)
{
if (p&1) y = y*x;
x = x*x;
p>>=1;
}
return y;
}
}A,v,cur; int n,m,flag[N<<2];
MX sum[N<<2],lazy_tag[N<<2];
LL a[N]; inline void push_up(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
} void build(int l,int r,int rt)
{
lazy_tag[rt].E();
if (l==r)
{
sum[rt] = A^a[l];
return;
}
int m = (l+r)>>1;
build(lson),build(rson);
push_up(rt);
} inline void push_down(int rt)
{
if (!flag[rt]) return;
flag[rt<<1] = flag[rt<<1|1] = 1;
flag[rt] = 0;
sum[rt<<1]=sum[rt<<1]*lazy_tag[rt];
sum[rt<<1|1]=sum[rt<<1|1]*lazy_tag[rt];
lazy_tag[rt<<1] = lazy_tag[rt<<1]*lazy_tag[rt];
lazy_tag[rt<<1|1] = lazy_tag[rt<<1|1]*lazy_tag[rt];
lazy_tag[rt].E();
} void up_data(int L,int R,int x,int l,int r,int rt)
{
if (L<= l && r <= R)
{
lazy_tag[rt]=lazy_tag[rt]*cur;
sum[rt] = sum[rt]*cur;
flag[rt] = 1;
return;
}
push_down(rt);
int m = (l+r)>>1;
if (L <= m) up_data(L,R,x,lson);
if (m < R) up_data(L,R,x,rson);
push_up(rt);
} MX Q(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R)
return sum[rt];
push_down(rt);
int m = (l+r)>>1;
MX temp1,temp2;
temp1.O(),temp2.O();
if (L <= m) temp1 = Q(L,R,lson);
if (m < R) temp2 = Q(L,R,rson);
temp1 = temp1 + temp2;
return temp1;
} LL query(int l,int r)
{
MX temp = Q(l,r,1,n,1);
temp = temp*v;
return temp.v[1][2];
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
ios::sync_with_stdio(false),cin.tie(0);//scanf,puts,printf not use
cin >> n >> m;
rep1(i,1,n) cin >> a[i];
A.v[1][1] = 0,A.v[1][2] = A.v[2][1] = A.v[2][2] = 1;
v.v[1][1] = v.v[1][2] = v.v[2][1] = 0,v.v[2][2] = 1;
build(1,n,1);
rep1(i,1,m)
{
int type;
cin >> type;
if (type==1)
{
int l,r,x;
cin >> l >> r >> x;
cur = A^x;
up_data(l,r,x,1,n,1);
}
else
{
int l,r;
cin >> l >> r;
cout << query(l,r) << endl;
}
}
return 0;
}

【codeforces 719E】Sasha and Array的更多相关文章

  1. 【24.17%】【codeforces 721D】Maxim and Array

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  2. 【codeforces 754A】Lesha and array splitting

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. 【Codeforces 258B】 Sort the Array

    [题目链接] http://codeforces.com/contest/451/problem/B [算法] 模拟 在序列中找到一段单调递增的子序列,将这段序列反转,然后判断序列是否变得单调递增,即 ...

  4. codeforces 719E E. Sasha and Array(线段树)

    题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...

  5. 【44.19%】【codeforces 727C】Guess the Array

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  6. 【Codeforces 1042D】Petya and Array

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 把a[i]处理成前缀和 离散化. 枚举i从1..n假设a[i]是区间和的a[r] 显然我们需要找到a[r]-a[l]<t的l的个数 即a ...

  7. 【codeforces 1109B】Sasha and One More Name

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 如果这个回文串的左半部分,字母全是一样的. 那么显然不可能再分出来了,因为不管怎么分怎么排列,最后肯定都只能和原串一样. 所以无解 其他情况下 ...

  8. 【Codeforces 1114B】Yet Another Array Partitioning Task

    [链接] 我是链接,点我呀:) [题意] 让你把数组分成k个连续的部分 使得每个部分最大的m个数字的和最大 [题解] 把原数组降序排序 然后选取前m*k个数字打标记 然后对于原数组 一直贪心地取 直到 ...

  9. 【Codeforces 1109C 】Sasha and a Patient Friend

    Codeforces 1109 C 题意:现在有个碗,每时每刻其中的水量都会加一个整数(可以为负). 给\(n\)个询问,询问有\(3\)种类型: \(1\ t\ s\):将从第\(t\)秒开始水量增 ...

随机推荐

  1. C语言遍历文件和文件夹——————【Badboy】

    [cpp] #include #include #include #include #include #include #include #define MAX_PATH_LENGTH 512 #de ...

  2. SPOJ 10628 Count on a tree (lca+主席树)

    题意:给定一棵有n个结点的树,每一个点有一个权值.共同拥有m个询问.对于每一个询问(u,v,k),回答结点u至v之间第k小的点的权值. 思路:主席树+lca.首先指定一个根结点dfs一次并在此过程中建 ...

  3. WinForm使用CefSharp内嵌chrome浏览器

    先贴运行图:亲测可用!以图为证! 开始!1.创建winform程序,使用.NET 4.5.2或以上(vs2010最高支持.NET 4.0,我使用的是vs2017).这一步容易忽略,简单的说就是将项目. ...

  4. 【cl】测试用例【文本框-电子邮箱】

    电子邮箱控件用例: 1.只输入字母,如:abc 2.只输入数字,如:123 3.空白.空格或回车等 4.特殊的字符,如:¥,$等 5.上述四种的组合 6.不正确的邮箱组合: ①.abc@sohucom ...

  5. POJ 1442 Black Box(优先队列)

    题目地址:POJ 1442 这题是用了两个优先队列,当中一个是较大优先.还有一个是较小优先. 让较大优先的队列保持k个.每次输出较大优先队列的队头. 每次取出一个数之后,都要先进行推断,假设这个数比較 ...

  6. [Linux]history 显示命令执行的时间

    显示历史命令之行时间 这里的环境是centos5.8 vim  ~/.bashrc 或者 ~/.bash_profile 增加 export HISTTIMEFORMAT="%F %T  & ...

  7. C - Ilya and Sticks(贪心)

    Problem description In the evening, after the contest Ilya was bored, and he really felt like maximi ...

  8. jah老师中关于集合的总结

    --------概述:1.Java 集合就像一种容器,可以把多个对象的引用放入容器中 2.Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组3.Java 集合可分为 S ...

  9. RFID 知识的学习

    * 部分资料来自我们博士的PPT,部分来自网络和他人的论文. * 我们使用的教材是清华大学出版社出版的<智能卡技术(第四版)——IC卡.RFID标签与物联网(清华大学计算机系列教材)>(王 ...

  10. chrome、firefox、IE中input输入光标位置错位解决方案

    以前在项目里碰到过一个问题 input输入框用一个背景图模拟,设置height和line-height一样的高度,使里面的输入文字能够居中, 在FF下出现的情况是:点击input时,输入光标其实上跟i ...