Codeforces 446-C DZY Loves Fibonacci Numbers 同余 线段树 斐波那契数列
4 seconds
256 megabytes
standard input
standard output
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 n integers: 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.
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.
For each query of the second type, print the value of the sum on a single line.
4 4
1 2 3 4
1 1 4
2 1 4
1 2 4
2 1 3
17
12
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.
官方题解:
As we know,
Fortunately, we find that
So,
With multiplicative inverse, we find,
Now,
As you see, we can just maintain the sum of a Geometric progression
This is a simple problem which can be solved with segment tree in .
这道题是Fibonacci数列通项公式的应用,比较经典。至少我是不可能想到斐波那契数列与等比数列有任何关联。还有一点,在程序内层循环中,快速幂的时间复杂度是不容忽视的(估计是线段树写抽了),这里既然公比恒定,可先与处理一下。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define MAXN 310000
#define MAXT 1210000
#define MOD 1000000009
#define lch (now<<1)
#define rch (now<<1^1)
void nextInt(int &x)
{
char ch;
x=;
while (ch=getchar(),ch>''||ch<'');
do
x=x*+ch-'';
while (ch=getchar(),ch<=''&&ch>='');
}
int n,m;
typedef long long qword;
int num[MAXN];
qword val1,val2,val3,val4,val3_n,val4_n,mod;
qword val3_pow[MAXN],val4_pow[MAXN];
qword pow_mod(qword x,qword y,int mod)
{
qword ret=;
while (y)
{
if (y&)ret=ret*x%mod;
x=x*x%mod;
y>>=;
}
return ret;
}
struct node
{
int l,r;
qword sum;
qword inc3,inc4;
}tree[MAXT];
inline void update_sum_3(int now,int inc3)
{
qword temp;
temp=inc3*(val3_pow[tree[now].r-tree[now].l+]-)%MOD*val3_n%MOD;
// temp=(temp+MOD)%MOD;
tree[now].sum=(tree[now].sum+temp)%MOD;
}
inline void update_sum_4(int now,int inc4)
{
qword temp;
temp=inc4*(val4_pow[tree[now].r-tree[now].l+]-)%MOD*val4_n%MOD;
temp=(-temp+MOD)%MOD;
tree[now].sum=(tree[now].sum+temp)%MOD;
}
inline void down(int now)
{
if (tree[now].l==tree[now].r)
{
if (tree[now].inc3)
{
tree[now].inc3=;
}
if (tree[now].inc4)
{
tree[now].inc4=;
}
return ;
}
if (tree[now].inc3)
{
qword temp;
tree[lch].inc3=(tree[lch].inc3+tree[now].inc3)%MOD;
// tree[lch].inc3%=MOD;
update_sum_3(lch,tree[now].inc3);
tree[rch].inc3+=temp=val3_pow[tree[lch].r-tree[lch].l+]*tree[now].inc3%MOD;
tree[rch].inc3%=MOD;
update_sum_3(rch,temp);
tree[now].inc3=;
}
if (tree[now].inc4)
{
qword temp;
tree[lch].inc4+=tree[now].inc4;
tree[lch].inc4%=MOD;
update_sum_4(lch,tree[now].inc4);
tree[rch].inc4+=temp=val4_pow[tree[lch].r-tree[lch].l+]*tree[now].inc4%MOD;
tree[rch].inc4%=MOD;
update_sum_4(rch,temp);
tree[now].inc4=;
}
}
inline void update(int now)
{
if (tree[now].l!=tree[now].r)
tree[now].sum=(tree[lch].sum+tree[rch].sum)%MOD;
}
void init()
{
/*//{{{
int i;
for (i=1;i<MOD;i++)
{
if ((qword)i*i%MOD==5)
{
val1=i;
break;
}
}
cout<<val1<<endl;
for (i=1;i<MOD;i++)
{
if ((qword)i*5%MOD==val1)
{
val2=i;
break;
}
}
cout<<val2<<endl;
for (i=1;i<MOD;i++)
{
if ((qword)i*2%MOD-1==val1)
{
val3=i;
break;
}
}
cout<<val3<<endl;
for (i=1;i<MOD;i++)
{
if ((qword)i*2-1==(-val1+MOD)%MOD)
{
val4=i;
break;
}
}
cout<<val4<<endl;//}}}*/
val1=;//sqrt(5)
val2=;//sqrt(5)/5
val3=;//(1+sqrt(5))/2
val4=;//(1-sqrt(5))/2
int i;
qword temp=val3;
val3_pow[]=;
for (i=;i<MAXN;i++)
{
val3_pow[i]=val3_pow[i-]*val3%MOD;;
}
val4_pow[]=;
for (i=;i<MAXN;i++)
{
val4_pow[i]=val4_pow[i-]*val4%MOD;
}
val3_n=pow_mod(val3-,MOD-,MOD);
val4_n=pow_mod(val4-,MOD-,MOD);
//fib(n)=val2*(val3^n-val4^n);
}
void build_tree(int now,int l,int r)
{
tree[now].l=l;
tree[now].r=r;
if (l==r)
{
tree[now].sum=num[l];
return ;
}
int mid=(l+r)/;
build_tree(lch,l,mid);
build_tree(rch,mid+,r);
update(now);
}
void add_val(int now,int l,int r,int rk)
{
if (tree[now].l==l&&tree[now].r==r)
{
qword temp;
temp=val2*val3%MOD*val3_pow[rk]%MOD;
tree[now].inc3=(tree[now].inc3+temp)%MOD;
update_sum_3(now,temp);
temp=val2*val4%MOD*val4_pow[rk]%MOD;
tree[now].inc4=(tree[now].inc4+temp)%MOD;
update_sum_4(now,temp);
return ;
}
down(now);
int mid=(tree[now].l+tree[now].r)>>;
if (r<=mid)
{
add_val(lch,l,r,rk);
update(now);
return ;
}
if (mid<l)
{
add_val(rch,l,r,rk);
update(now);
return ;
}
add_val(lch,l,mid,rk);
add_val(rch,mid+,r,rk-l+mid+);
update(now);
}
//ok
qword query(int now,int l,int r)
{
if (tree[now].l==l&&tree[now].r==r)
{
return tree[now].sum;
}
down(now);
int mid=(tree[now].l+tree[now].r)>>;
if (r<=mid)
return query(lch,l,r);
if (mid<l)
return query(rch,l,r);
return (query(lch,l,mid)+query(rch,mid+,r))%MOD;
} int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
//scanf("%d%d",&n,&m);
nextInt(n);
nextInt(m);
int i,j,k,x,y,z;
init();
for (i=;i<=n;i++)
nextInt(num[i]);
build_tree(,,n);
while (m--)
{
nextInt(x);
nextInt(y);
nextInt(z);
if (x==)
{
add_val(,y,z,);
}else
{
printf("%I64d\n",query(,y,z));
}
}
}
Codeforces 446-C DZY Loves Fibonacci Numbers 同余 线段树 斐波那契数列的更多相关文章
- [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)
[Codeforces 316E3]Summer Homework(线段树+斐波那契数列) 顺便安利一下这个博客,给了我很大启发(https://gaisaiyuno.github.io/) 题面 有 ...
- 【CF446C】DZY Loves Fibonacci Numbers (线段树 + 斐波那契数列)
Description 看题戳我 给你一个序列,要求支持区间加斐波那契数列和区间求和.\(~n \leq 3 \times 10 ^ 5, ~fib_1 = fib_2 = 1~\). Solut ...
- 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 ...
- Codeforces 316E3 线段树 + 斐波那切数列 (看题解)
最关键的一点就是 f[ 0 ] * a[ 0 ] + f[ 1 ] * a[ 1 ] + ... + f[ n - 1] * a[ n - 1] f[ 1 ] * a[ 0 ] + f[ 2 ] * ...
- [莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II
题目大意:给出一个长度为n的数列a. 对于一个询问lj和rj.将a[lj]到a[rj]从小到大排序后并去重.设得到的新数列为b,长度为k,求F1*b1+F2*b2+F3*b3+...+Fk*bk.当中 ...
- codeforces 446C DZY Loves Fibonacci Numbers(数学 or 数论+线段树)(两种方法)
In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation F1 ...
- 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 ...
随机推荐
- android账号与同步之同步实现
上一篇博文我先介绍了账号与同步的账号管理,这篇就介绍一下还有一部分.就是android给提供的sync同步机制的使用. 事实上sync机制的使用和上一篇博文中介绍的账号管理非常类似,也是基于binde ...
- Sae配置Java数据库连接
Sae配置Java数据库连接 Sae在Java中配置mysql数据库 >>>>>>>>>>>>>>>>& ...
- Andriod中WebView加载登录界面获取Cookie信息并同步保存,使第二次不用登录也可查看个人信息。
Android使用WebView加载登录的html界面,则通过登录成功获取Cookie并同步,可以是下一次不用登录也可以查看到个人信息,注:如果初始化加载登录,可通过缓存Cookie信息来验证是否要加 ...
- Entity Framework Demo(一) 简单搭建环境
Entity Framwork(实体框架,简称EF)是ORM(Object Relational Mapping,对象映射关系)的一个解决方案. EF允许项目将数据库的表映射为实体,并封装了操作方法, ...
- html不同文档类型支持的元素标签
- Hello World深入理解
每个编程人员都知道第一个都是Hello World, 可是只是单知道 用,不知道为何会这样,就一直学的只是皮毛. 学东西,不能知其然而不知其所以然.这样永远达不到境界. 我们用编辑器eclipse 创 ...
- .Net之美读书系列(二):委托进阶
这次看书的知识点: 事件访问器 如果一个委托中注册了多个事件且需要获取其返回值的方法 委托的异常处理 委托处理超时的方法 异步委托 事件访问器 职能有: 1.对委托属性进行封装,不再直接该委托变量直接 ...
- Jsp内置对象-session
session内置对象介绍 个人理解:session因为是唯一的, session是与请求有关的会话期,它是java.servlet.http.HttpSession类的对象,用来表示和存储当前页面的 ...
- SQL 2012的分页
今天看到一篇文章介绍2012中的分页,就想测试一下新的分页方法比原先的有多少性能的提升,下面是我的测试过程(2012的分页语法这里不在做多的说明,MSDN上一搜就有): 首先我们来构造测试数据: -- ...
- ORACLE如何停止一个JOB
ORACLE如何停止一个JOB1 相关表.视图2 问题描述为同事解决一个因为网络连接情况不佳时,执行一个超长时间的SQL插入操作.既然网络状况不好,就选择了使用一次性使用JOB来完成该插入操作.在JO ...