Codeforces446C - DZY Loves Fibonacci Numbers
Description
给出一个\(n(n\leq3\times10^5)\)个数的序列,进行\(m(m\leq3\times10^5)\)次操作,操作有两种:
- 给区间\([L,R]\)加上一个斐波那契数列,即\(\{a_L,a_{L+1},...,a_R\} \rightarrow \{a_L+F_1,a_{L+1}+F_2,...,a_R+F_{R-L+1}\}\)
- 询问区间\([L,R]\)的和,对\(10^9+9\)取模。
斐波那契数列:\(F_1=1,F_2=2\)且满足\(F_{n+2}=F_n+F_{n+1}\)。
Solution
容易知道,满足\(a_{n+2}=a_n+a_{n+1}\)的数列具有以下性质:
- 若\(c_n=a_n+b_n\),则\(c_1=a_1+b_1,c_2=a_2+b_2,c_{n+2}=c_n+c_{n+1}\)。
- 有通项公式\(a_n=F_{n-2}a_1+F_{n-1}a_2\)。
有前缀和公式\(\sum_{i=1}^n a_i=a_{n+2}-a_2\)。
下面依次进行证明。
证明1
\(c_{n+2}=a_{n+2}+b_{n+2}=(a_n+a_{n+1})+(b_n+b_{n+1})=(a_n+b_n)+(a_{n+1}+b_{n+1})=c_n+c_{n+1}\)
证明2
若当\(n\leq k\)时,\(a_n=F_{n-2}a_1+F_{n-1}a_2\),则
\(a_{k+1}=a_{k-1}+a_k=(F_{k-3}a_1+F_{k-2}a_2)+(F_{k-2}a_1+F_{k-1}a_2)=F_{k-1}a_1+F_ka_2\)
因为\(a_1=F_{-1}a_1+F_0\)(可以认为\(F_0=F_2-F_1=0,F_{-1}=F_1-F_0=1\)),\(a_2=F_0a_1+F_1a_2\)
所以\(\forall n\in\mathbb{Z},a_n=F_{n-2}a_1+F_{n-1}a_2\)。
证明3
\(\begin{align} 2\Sigma_{i=1}^n a_i &= (a_1+a_2+...+a_n)+(a_1+a_2+...+a_n) \\ &=a_1+(a_1+a_2)+(a_2+a_3)+...+(a_{n-1}+a_n)+a_n \\ &=a_1+a_n+(a_3+a_4...+a_{n+1}) \\ &=(a_1+a_2+...+a_n)-a_2+a_n+a_{n+1} \\ &=\Sigma_{i=1}^n a_i+a_{n+2}-a_2 \\ \Sigma_{i=1}^n a_i &=a_{n+2}-a_2 \end{align}\)
我们现在就可以用线段树维护这个序列了。线段树中的每个节点记录三个值\(f_1,f_2,sum\),表示该区间被加上了一个以\(f_1,f_2\)开头的数列,区间和为\(sum\)。
通过性质1,我们知道\(f_1,f_2\)可以叠加;
通过性质2,我们可以\(O(1)\)地将\(f_1,f_2\)下放;
通过性质3,我们可以\(O(1)\)地更新\(sum\)。时间复杂度\(O(nlogn)\)。
Code
//DZY Loves Fibonacci Numbers
#include <cstdio>
inline char gc()
{
static char now[1<<16],*S,*T;
if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}
return *S++;
}
inline int read()
{
int x=0,f=1; char ch=gc();
while(ch<'0'||'9'<ch) {if(ch=='-') f=-1; ch=gc();}
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
typedef long long lint;
int const N=3e5+10;
lint const P=1e9+9;
int n,m; lint F[N],a[N];
#define s sg[s0]
struct seg{lint f1,f2,sum;} sg[N*20];
void update(int s0,int len)
{
s.f1%=P,s.f2%=P;
s.sum=sg[s0<<1].sum+sg[s0<<1|1].sum+(s.f1*F[len]+s.f2*F[len+1]-s.f2),s.sum%=P;
}
void pushdown(int s0,int L0,int R0)
{
if(s.f1==0&&s.f2==0) return;
int mid=L0+R0>>1,Ls0=s0<<1,Rs0=Ls0|1;
sg[Ls0].f1+=s.f1; sg[Rs0].f1+=s.f1*F[mid-L0]+s.f2*F[mid-L0+1];
sg[Ls0].f2+=s.f2; sg[Rs0].f2+=s.f1*F[mid-L0+1]+s.f2*F[mid-L0+2];
s.f1=s.f2=0;
update(Ls0,mid-L0+1); update(Rs0,R0-mid);
}
void ins(int s0,int L0,int R0,int L,int R)
{
if(L<=L0&&R0<=R) {s.f1+=F[L0-L+1],s.f2+=F[L0-L+2],update(s0,R0-L0+1); return;}
pushdown(s0,L0,R0);
int mid=L0+R0>>1;
if(L<=mid) ins(s0<<1,L0,mid,L,R);
if(mid<R) ins(s0<<1|1,mid+1,R0,L,R);
update(s0,R0-L0+1);
}
lint query(int s0,int L0,int R0,int L,int R)
{
if(L<=L0&&R0<=R) return s.sum;
pushdown(s0,L0,R0);
lint res=0; int mid=L0+R0>>1;
if(L<=mid) res+=query(s0<<1,L0,mid,L,R);
if(mid<R) res+=query(s0<<1|1,mid+1,R0,L,R);
return res%P;
}
lint sumA[N];
int main()
{
n=read(),m=read();
F[1]=F[2]=1; for(int i=3;i<=n+1;i++) F[i]=(F[i-2]+F[i-1])%P;
for(int i=1;i<=n;i++) a[i]=read(),sumA[i]=sumA[i-1]+a[i];
int rt=1;
for(int i=1;i<=m;i++)
{
int opt=read(),L=read(),R=read();
if(opt==1) ins(rt,1,n,L,R);
else printf("%lld\n",(query(rt,1,n,L,R)+sumA[R]-sumA[L-1])%P);
}
return 0;
}
P.S.
CF怎么是个题就要开long long!?
不知道为什么要求对\(10^9+9\)取模,而不是\(10^9+7\)。
Codeforces446C - DZY Loves Fibonacci Numbers的更多相关文章
- 『题解』Codeforces446C DZY Loves Fibonacci Numbers
更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description In mathematical terms, the sequence \( ...
- Codeforces446C DZY Loves Fibonacci Numbers(线段树 or 分块?)
第一次看到段更斐波那契数列的,整个人都不会好了.事后看了题解才明白了一些. 首先利用二次剩余的知识,以及一些数列递推式子有下面的 至于怎么解出x^2==5(mod 10^9+9),我就不知道了,但是要 ...
- codeforces 446C DZY Loves Fibonacci Numbers(数学 or 数论+线段树)(两种方法)
In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation F1 ...
- Codeforces 446-C DZY Loves Fibonacci Numbers 同余 线段树 斐波那契数列
C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...
- cf446C DZY Loves Fibonacci Numbers
C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...
- Codeforces Round #FF 446 C. DZY Loves Fibonacci Numbers
參考:http://www.cnblogs.com/chanme/p/3843859.html 然后我看到在别人的AC的方法里还有这么一种神方法,他预先设定了一个阈值K,当当前的更新操作数j<K ...
- [CodeForces - 447E] E - DZY Loves Fibonacci Numbers
E DZY Loves Fibonacci Numbers In mathematical terms, the sequence Fn of Fibonacci numbers is define ...
- ACM学习历程—Codeforces 446C DZY Loves Fibonacci Numbers(线段树 && 数论)
Description In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence ...
- 【思维题 线段树】cf446C. DZY Loves Fibonacci Numbers
我这种maintain写法好zz.考试时获得了40pts的RE好成绩 In mathematical terms, the sequence Fn of Fibonacci numbers is de ...
随机推荐
- Python输出hello world(各行命令详解)
创建main.py文件并粘贴下面代码 点击右键运行Debug 'main'后,下方的Debug窗口会出现ImportError: No module named 'bottle'这样的提示,提示导入b ...
- 数据访问(DAO)
那些年,到处刮起了业务处理分层的大风,无论何时何地,都有某MVC框架.Spring管理的Service.以及iBatis和Hibernate等代表的DAO,SSH.SSI等成了标准.然而,我们仔细研究 ...
- MUI 图片上传实现
HTML代码 <!doctype html> <html> <head> <meta charset="UTF-8"> <ti ...
- 使用FileReader实现前端预览所选图片
需求描述 在浏览器环境下进开发网站(也就是B/S架构的应用),获取到当前设备上的图片后,希望可以在上传到服务器前简单预览一下图片内容. 具体实现 主要代码 html 部分 <input type ...
- c# excel print 打印 将所有列调整为一页
excel有时候列数比较多,行数也比较多,转换成xps文档的时候,一般是通过打印来实现. 由于打印的范围限制,所以会出现本来在一行的数据,由于列数比较多,溢出范围,被打印到两页了. 为解决这个问题,需 ...
- MySQL二进制日志binlog简单使用
MySQL数据库进行了哪些CUD操作,通过binlog二进制文件可以查看.binlog不仅可以记录CUD的操作(select操作不包括在内),还是主从备份的基础.主库的操作记录成binlog文件,定期 ...
- POJ [P2289] Jamie's Contact Groups
二分+二分图多重匹配 辣鸡ACM式读入 对于这种奇葩的读入方法,还是老老实实的用scanf吧 #include <iostream> #include <cstdio> #in ...
- CF 570D. Tree Requests [dsu on tree]
传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... ...
- C# 使用GDI制作垂直进度条(由下往上)
使用GDI+绘进度条的方式多种多样,可以封装一个UserControl,也可以直接使用一个控件来绘制(Label.Image.Panel等),甚至可以直接在winForm上画一个,关键代码没几行(这里 ...
- 3.C++内联函数,默认参数,占位参数
本章主要内容: 1)内联函数(替代宏代码段) 2)默认参数 3)占位参数 1.C++的内联函数分析 1.1讲解内联函数之前,首先回忆下之前讲的define宏定义: 之前讲过宏定义会经过预处理器进行文本 ...