传送门

解题思路:

这道题给了我们一个崭新的角度来看线段树。

我们常常使用的线段树是维护区间的函数的。

这里呢,提示我们线段树其实还可以维护递推。

美好的矩阵递推性质支持了这一功能。

或者说,对于递推项求和,可以使用线段树维护矩阵。

区间向前递推可以用懒惰标记记录递推矩阵。

区间的查询可以是子节点矩阵和。

这其实也是满足分配率的。

最后pushup,pushdown搞一搞就好了。

代码(闲来无事卡常码风突变):

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
typedef unsigned long long lnt;
typedef unsigned int ixt;
const lnt mod=(lnt)(1e9+);
struct squ{
lnt s[][];
inline void res(void)
{
memset(s,,sizeof(s));
return ;
}
inline void O1(void)
{
for(register int i=;i<;i++)
s[i][i]=;
return ;
}
inline squ friend operator + (const squ &a,const squ &b)
{
squ ans;
for(register int i=;i<;i++)
{
for(register int j=;j<;j++)
{
ans.s[i][j]=(a.s[i][j]+b.s[i][j])%mod;
}
}
return ans;
}
inline squ friend operator * (const squ &a,const squ &b)
{
squ ans;
for(register int i=;i<;i++)
{
for(register int j=;j<;j++)
{
ans.s[i][j]=;
for(register int k=;k<;k++)
{
ans.s[i][j]=(ans.s[i][j]+a.s[i][k]*b.s[k][j])%mod;
}
}
}
return ans;
}
inline squ friend operator ^ (squ a,lnt b)
{
squ ans=a;
b--;
while(b)
{
if(b&)
ans=ans*a;
a=a*a;
b=b/;
}
return ans;
}
}sta,pro;
struct trnt{
squ sum;
squ lzt;
bool op;
}tr[];
ixt n,m;
ixt a[];
inline void read(ixt &ans)
{
ans=;
char ch=getchar();
while(ch<''||ch>'')
ch=getchar();
while(ch>=''&&ch<='')
ans=ans*+ch-'',ch=getchar();
return ;
}
inline squ Fib(const lnt &x)
{
squ tmp=pro^x;
return tmp*sta;
}
inline void pushup(const int &spc)
{
tr[spc].sum=tr[lll].sum+tr[rrr].sum;
return ;
}
inline void add(const int &spc,const squ &v)
{
tr[spc].op=true;
tr[spc].lzt=v*tr[spc].lzt;
tr[spc].sum=v*tr[spc].sum;
return ;
}
inline void pushdown(const int &spc)
{
if(tr[spc].op)
{
add(lll,tr[spc].lzt);
add(rrr,tr[spc].lzt);
tr[spc].lzt.res();
tr[spc].lzt.O1();
tr[spc].op=;
}
return ;
}
inline void build(const int &l,const int &r,const int &spc)
{
tr[spc].lzt.res();
tr[spc].lzt.O1();
if(l==r)
{
tr[spc].sum=Fib(a[l]);
return ;
}
int mid=(l+r)>>;
build(l,mid,lll);
build(mid+,r,rrr);
pushup(spc);
return ;
}
inline void update(const int &l,const int &r,const int &ll,const int &rr,const int &spc,const squ &v)
{
if(ll>r||l>rr)
return ;
if(ll<=l&&r<=rr)
{
add(spc,v);
return ;
}
int mid=(l+r)>>;
pushdown(spc);
update(l,mid,ll,rr,lll,v);
update(mid+,r,ll,rr,rrr,v);
pushup(spc);
return ;
}
inline squ query(const int &l,const int &r,const int &ll,const int &rr,const int &spc)
{
squ ans;
ans.res();
if(l>rr||ll>r)
return ans;
if(ll<=l&&r<=rr)
return tr[spc].sum;
int mid=(l+r)>>;
pushdown(spc);
return query(l,mid,ll,rr,lll)+query(mid+,r,ll,rr,rrr);
}
int main()
{
sta.s[][]=;
sta.s[][]=;
pro.s[][]=;
pro.s[][]=;
pro.s[][]=;
read(n);
read(m);
for(register int i=;i<=n;i++)
scanf("%d",&a[i]);
build(,n,);
while(m--)
{
ixt opt;
read(opt);
if(opt==)
{
ixt l,r,x;
read(l);
read(r);
read(x);
if(!x)
continue;
squ tmp=pro^x;
update(,n,l,r,,tmp);
}else{
ixt l,r;
read(l);
read(r);
printf("%I64u\n",(query(,n,l,r,).s[][]%mod+mod)%mod);
}
}
return ;
}

Codeforces 718C. Sasha and Array(线段树)的更多相关文章

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

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

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

  3. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

  4. CodeForces 718C Sasha and Array

    线段树. 线段树维护区间矩阵和,操作都是最简单的线段树.$lazy$标记不要记录乘了几次,直接记录乘了几次之后的矩阵就可以了,不然每次下传的时候再算一遍时间复杂度会提高. #pragma commen ...

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

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

  6. CF718C Sasha and Array 线段树+矩阵加速

    正解:线段树 解题报告: 传送门! 首先这种斐波拉契,又到了1e9的范围,又是求和什么的,自然而然要想到矩阵加速昂 然后这里主要是考虑修改操作,ai+=x如果放到矩阵加速中是什么意思呢QAQ? 那不就 ...

  7. CF718C Sasha and Array 线段树 + 矩阵乘法

    有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$   直接求不好求,改成矩阵乘法的形式:  $a_{i}=M^x\times ...

  8. CF718C Sasha and Array [线段树+矩阵]

    我们考虑线性代数上面的矩阵知识 啊呸,是基础数学 斐波那契的矩阵就不讲了 定义矩阵 \(f_x\) 是第 \(x\) 项的斐波那契矩阵 因为 \(f_i * f_j = f_{i+j}\) 然后又因为 ...

  9. Codeforces 719 E. Sasha and Array (线段树+矩阵运算)

    题目链接:http://codeforces.com/contest/719/problem/E 题意:操作1将[l, r] + x; 操作2求f[l] + ... + f[r]; 题解:注意矩阵可以 ...

随机推荐

  1. HDU 5386 Cover(模拟)

    Cover Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Subm ...

  2. 怎样给UINavigationBar加入button?

    Mads Mobæk:给UINavigationBar加入button的演示样例代码 1 2 3 4 5 6 7 8 UIBarButtonItem *rightButton = [[UIBarBut ...

  3. legend---二、如何降低编程复杂度

    legend---二.如何降低编程复杂度 一.总结 一句话总结:配置文件,数据库 个性的东西可以一起写入数据库,那么编程复杂度会大幅降低,页面灵活度也大幅降低(特有属性写进数据库) 比如不同难度的颜色 ...

  4. 22.IntelliJ IDEA 切换 project

    转自:https://blog.csdn.net/qwdafedv/article/details/73838628?utm_source=blogxgwz0 1.file->open 2.选择 ...

  5. Android 使用Retrofit获取JSON数据

    在大家使用网络请求的时候,往往会出现一种情况:需要拿到服务器返回来的JSON字符串,而Retrofit会默认将Json解析,而又没有直接暴露出拿到Json字符串的方法: 今天测接口的时候,发现当数据正 ...

  6. 分享vue ui时间组件用法

    //js code var jiaban = { template:` <i-form v-ref:form_jb :model="form_jb" :rules=" ...

  7. UESTC 1584

    http://acm.uestc.edu.cn/#/problem/show/1584 Washi与Sonochi的约定 Time Limit: 3000/1000MS (Java/Others)   ...

  8. UESTC 1599 wtmsb

    这天,AutSky_JadeK看到了n张图片,他忍不住说道:“我TM社保!”. 每张图片有一个社保值,他可以合并两张图片,合并所得的图片的社保值是原来两张图片的社保值之和. 每次合并需要消耗的体力也是 ...

  9. 休假结束,Linus重回内核开发岗位

    在休假反省一个多月之后,Linus Torvalds 又回来了.10 月 22 日爱丁堡举行的欧洲开源峰会上,Linus Torvalds 将与内核维护者们碰头,这是他重新接管Linux内核开发的第一 ...

  10. codevs 1019 集合论与图论

    1019 集合论与图论  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 集合论与图论对于小松来说 ...