[CodeForces - 447E] E - DZY Loves Fibonacci Numbers
E DZY Loves Fibonacci Numbers
In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation
F1 = 1; F2 = 1; Fn = Fn - 1 + Fn - 2 (n > 2).
DZY loves Fibonacci numbers very much. Today DZY gives you an array consisting of nintegers: a1, a2, ..., an. Moreover, there are m queries, each query has one of the two types:
- Format of the query "1 l r". In reply to the query, you need to add Fi - l + 1 to each element ai, where l ≤ i ≤ r.
- Format of the query "2 l r". In reply to the query you should output the value of
modulo 1000000009 (109 + 9).
Help DZY reply to all the queries.
Input
The first line of the input contains two integers n and m (1 ≤ n, m ≤ 300000). The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) — initial array a.
Then, m lines follow. A single line describes a single query in the format given in the statement. It is guaranteed that for each query inequality 1 ≤ l ≤ r ≤ n holds.
Output
For each query of the second type, print the value of the sum on a single line.
Example
4 41 2 3 41 1 42 1 41 2 42 1 3
1712
Note
After the first query, a = [2, 3, 5, 7].
For the second query, sum = 2 + 3 + 5 + 7 = 17.
After the third query, a = [2, 4, 6, 9].
For the fourth query, sum = 2 + 4 + 6 = 12.
题目的大意就是,定义了fib数列前两项F[1]=1,F[2]=1。给出整数n,m,再给出n个数和m项操作。
每个操作包含三个数op,l,r,若op=1,就在[l,r]的区间相应加上F[1,r-l+1](每个数对应着加),若op=2,就将[l,r]中所有数统计和并输出。
首先,我们要知道,fib数列有个特殊的性质_两个fib数列相加,还是fib数列,只是前两项的值变动了而已(从而导致后面的数变动).
那么,根据这个性质,就可以通过累计的方法实现_用线段树进行维护.
首先,我们需要知道一些性质:
设fib[1]=a,fib[2]=b,则fib[n]=fib[n-1]*b+fib[n-2]*a.(可推)
fib[1]+fib[2]+fib[3]+......+fib[n]=fib[n+2]-fib[2].(可推)
通过这两个性质,我们可以巧妙的记录线段树上每一个节点的前两个(fib[1],fib[2])的值,然后计算出这个节点上[L,R],所有数的和.
怎么来?
我们对于每一个线段树上的节点,都记录两个值,ta,tb,分别表示这个区间前两项的值,在更新时,
void upt(int now,int fir,int sec,int len){ T[now].ta=(T[now].ta+fir)%TT,T[now].tb=(T[now].tb+sec)%TT; T[now].key=((]-(long long)sec)%TT; }
其中前两句是将标记累计,最后以句就是顺带计算出这个节点的值.
同时,在pushdown函数中,也要对此进行更新.
void push_down(int now){ if (!T[now].ta&&!T[now].tb) return; int L=T[now].L,R=T[now].R; upt(now<<,T[now].ta,T[now].tb,mid-L+); ,a,b; a=((]+(long long)T[now].tb*fib[len])%TT; b=((])%TT; upt(now<<|,a,b,R-mid); T[now].ta=T[now].tb=; }
其中,对于某个节点的子节点,有两段.一段[L,mid],一段[mid+1,R].
那么更新[L,mid]时,它的前缀和当前节点是一样的,所以不需改动信息,直接下传.
更新[mid+1,R]时,需要重新计算出这段区间前两项的值(这可以用上面说的性质算),然后才能下传.
最后下传完了记得把标记清空.
不过不知道为什么,我的线段树开4,5倍空间会炸,开10倍才不炸,很玄学......
#include<cstdio> #include<cstring> #include<algorithm> #define mid ((L+R)>>1) using namespace std; ,maxn=; int n,m,a[maxn],fib[maxn]; ]; int read(){ ; char ch=getchar(); ') ch=getchar(); +ch-',ch=getchar(); return x; } void make(int now,int L,int R){ T[now].L=L,T[now].R=R; if (L==R){T[now].key=a[L]; return;} make(now<<,L,mid),make(now<<|,mid+,R); T[now].key=(T[now<<].key+T[now<<|].key)%TT; } void upt(int now,int fir,int sec,int len){ T[now].ta=(T[now].ta+fir)%TT,T[now].tb=(T[now].tb+sec)%TT; T[now].key=((]-(long long)sec)%TT; } void push_down(int now){ if (!T[now].ta&&!T[now].tb) return; int L=T[now].L,R=T[now].R; upt(now<<,T[now].ta,T[now].tb,mid-L+); ,a,b; a=((]+(long long)T[now].tb*fib[len])%TT; b=((])%TT; upt(now<<|,a,b,R-mid); T[now].ta=T[now].tb=; } void alter(int now,int aimL,int aimR){ int L=T[now].L,R=T[now].R; if (L>aimR||R<aimL) return; ],fib[L-aimL+],R-L+); push_down(now); return;} push_down(now); alter(now<<,aimL,aimR),alter(now<<|,aimL,aimR); T[now].key=(T[now<<].key+T[now<<|].key)%TT; } int seek(int now,int aimL,int aimR){ int L=T[now].L,R=T[now].R; ; if (L>=aimL&&R<=aimR) return T[now].key; push_down(now); ,aimL,aimR)+seek(now<<|,aimL,aimR))%TT; } int main(){ n=read(),m=read(),memset(T,,sizeof T); ; i<=n; i++) a[i]=read(); make(,,n); fib[]=,fib[]=fib[]=; ; i<=n+; i++) fib[i]=(fib[i-]+fib[i-])%TT; ; i<=m; i++){ int tp=read(),L=read(),R=read(); ) alter(,L,R); ,L,R)); } ; }
[CodeForces - 447E] E - DZY Loves Fibonacci Numbers的更多相关文章
- 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 ...
- Codeforces Round #FF 446 C. DZY Loves Fibonacci Numbers
參考:http://www.cnblogs.com/chanme/p/3843859.html 然后我看到在别人的AC的方法里还有这么一种神方法,他预先设定了一个阈值K,当当前的更新操作数j<K ...
- ACM学习历程—Codeforces 446C DZY Loves Fibonacci Numbers(线段树 && 数论)
Description In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence ...
- codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新
DZY Loves Fibonacci Numbers Time Limit:4000MS Memory Limit:262144KB 64bit IO Format:%I64d &a ...
- Codeforces 446C —— DZY Loves Fibonacci Numbers(线段树)
题目:DZY Loves Fibonacci Numbers 题意比較简单,不解释了. 尽管官方的题解也是用线段树,但还利用了二次剩余. 可是我没有想到二次剩余,然后写了个感觉非常复杂度的线段树,还是 ...
- 『题解』Codeforces446C DZY Loves Fibonacci Numbers
更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description In mathematical terms, the sequence \( ...
- cf446C DZY Loves Fibonacci Numbers
C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...
- Codeforces446C - DZY Loves Fibonacci Numbers
Portal Description 给出一个\(n(n\leq3\times10^5)\)个数的序列,进行\(m(m\leq3\times10^5)\)次操作,操作有两种: 给区间\([L,R]\) ...
随机推荐
- 【NOIP 2016】Day2 T3 愤怒的小鸟
Problem Description \(Kiana\) 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 \((0,0)\) 处,每次 \(Kiana\ ...
- POJ 3415 Common Substrings(长度不小于K的公共子串的个数+后缀数组+height数组分组思想+单调栈)
http://poj.org/problem?id=3415 题意:求长度不小于K的公共子串的个数. 思路:好题!!!拉丁字母让我Wa了好久!!单调栈又让我理解了好久!!太弱啊!! 最简单的就是暴力枚 ...
- 理解 Redis(1) - Redis 简介
Redis 的含义 全称: REmote DIctionary Server 远程词典服务器 由于支持 string, list, set, ordered set, hash 等多重数据结构, 因此 ...
- ngui项目花屏问题
项目用的ngui 最近在金立手机上遇到一个问题就是 启动的时候会花一下屏幕 一闪而过 由于ngui默认camera使用的是clear depth 所以按照网上的办法修改 color 跟skybo ...
- linq to sql and linq to object 总结
Enumable类型是linq to object 是一个很特殊的类型 这个类型的数据源都是在程序的内存中 Queryable类型是 Linq to sql 对数据库进行操作都是这个类型 ...
- openstack环境搭建常用命令
1,编辑/etc/selinux/config文件,关闭selinux SELINUX=disabled 2,清空iptables规则并保存 # iptables -F # service iptab ...
- WIN7右键在目录当前打开命令行Cmd窗口
Win7系统大家习惯“Win+R”的组合键打开命令提示符. 2. 通常情况下,我们点击鼠标右键是没有命令行选项的.. 3.在桌面上先按住Shift键,然后鼠标右键,出现选项“在此处打开命令窗口(W)” ...
- Linux-Ubuntu16.0.4相关命令
1.更新软件源 sudo apt-get update 2.shell命令 基本格式:命令 [-选项] [-命令参数] ls #查看当前文件夹下的文件 ls -l XXXX #查看XXXX文件夹下的 ...
- 在python中使用正则表达式(三)
这里主要说一下贪婪匹配和非贪婪匹配 贪婪匹配:匹配尽可能多的字符: 非贪婪匹配:匹配尽可能少的字符 python的正则匹配默认是贪婪匹配 例子: >>> re.match(r'^ ...
- xpath是什么(入门教程)
xpath是什么(入门教程) 一.总结 一句话总结:一句话,XPath 是一门在 XML 文档中查找信息的语言.简单来说,html类似于xml结构,但是没有xml格式那么严格. 在xml中查找信息 包 ...