Codeforces 718C. Sasha and Array(线段树)
传送门
解题思路:
这道题给了我们一个崭新的角度来看线段树。
我们常常使用的线段树是维护区间的函数的。
这里呢,提示我们线段树其实还可以维护递推。
美好的矩阵递推性质支持了这一功能。
或者说,对于递推项求和,可以使用线段树维护矩阵。
区间向前递推可以用懒惰标记记录递推矩阵。
区间的查询可以是子节点矩阵和。
这其实也是满足分配率的。
最后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(线段树)的更多相关文章
- codeforces 719E E. Sasha and Array(线段树)
题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...
- 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 ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- CodeForces 718C Sasha and Array
线段树. 线段树维护区间矩阵和,操作都是最简单的线段树.$lazy$标记不要记录乘了几次,直接记录乘了几次之后的矩阵就可以了,不然每次下传的时候再算一遍时间复杂度会提高. #pragma commen ...
- CF719E. Sasha and Array [线段树维护矩阵]
CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...
- CF718C Sasha and Array 线段树+矩阵加速
正解:线段树 解题报告: 传送门! 首先这种斐波拉契,又到了1e9的范围,又是求和什么的,自然而然要想到矩阵加速昂 然后这里主要是考虑修改操作,ai+=x如果放到矩阵加速中是什么意思呢QAQ? 那不就 ...
- CF718C Sasha and Array 线段树 + 矩阵乘法
有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$ 直接求不好求,改成矩阵乘法的形式: $a_{i}=M^x\times ...
- CF718C Sasha and Array [线段树+矩阵]
我们考虑线性代数上面的矩阵知识 啊呸,是基础数学 斐波那契的矩阵就不讲了 定义矩阵 \(f_x\) 是第 \(x\) 项的斐波那契矩阵 因为 \(f_i * f_j = f_{i+j}\) 然后又因为 ...
- Codeforces 719 E. Sasha and Array (线段树+矩阵运算)
题目链接:http://codeforces.com/contest/719/problem/E 题意:操作1将[l, r] + x; 操作2求f[l] + ... + f[r]; 题解:注意矩阵可以 ...
随机推荐
- php中局部变量和全局变量
php中局部变量和全局变量 代码1:函数内部使用函数外部变量错误方法 <?php $name = 'fish'; function animal() { echo $name; } animal ...
- Gym - 100203G Good elements 水+模拟
题意:good element的定义是a[i]在1~i-1中任取三个数(可以重复)的和能等于a[i] 思路:vis[x]标记一下任两个数的和,处理a[i]时枚举1~i-1判断vis[a[i] - a[ ...
- 在performancepoint里面建立数据源的时候,总是发生以下的报警
就是我在performancepoint里面建立数据源的时候,总是发生以下的报警. 在管理中心主页的“应用程序管理”部分,单击“管理服务应用程序”,然后单击“PerformancePoint Se ...
- K-近邻算法学习
# -- coding: utf-8 -- from numpy import * import operator def createDataSet(): group = array([[1.0,1 ...
- 【Henu ACM Round #13 E】Spy Syndrome 2
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 对m个串建立一棵字典树. 然后对主串. 尝试从第一个位置开始.在字典树中尝试匹配 如果匹配到了位置i 就再从位置i+1开始尝试匹配 ...
- codeforces 543 C Remembering Strings
题意:若一个字符串集合里的每一个字符串都至少有一个字符满足在i位上,仅仅有它有,那么这个就是合法的,给出全部串的每一个字符修改的花费,求变成合法的最小代价. 做法:dp[i][j].前i个串的状态为j ...
- POJ2823 Sliding Window【双端队列】
求连续的k个中最大最小值,k是滑动的,每次滑动一个 用双端队列维护可能的答案值 假设要求最小值,则维护一个单调递增的序列 对一開始的前k个,新增加的假设比队尾的小.则弹出队尾的,直到新增加的比队尾大. ...
- 用YourAPP开发网络状态提醒应用
如今的通信真是方便,走到哪里都有网络.Wifi的利用已经到了很普及的程度.即使走到没有wifi信号的地方,利用手机信号也能上网.(若是连手机信号都没有,那就没办法了) 智能手机的使用也大慷慨面了各个年 ...
- js---11运算符,流程控制,真假
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- android framework 02
Android底层开发1.安装Ubuntu系统2.Ubuntu配置开发环境: sudo apt-get install git-core gnupg flex bison gperf zip sudo ...