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 ...
随机推荐
- [PHP] find ascii code in string
if (strpos($data ,chr(0x95)) !== false) { echo 'true'; }else{ echo "false"; }
- PHP汉字转拼音的两种方法+PHP提取汉字(中文)方法
方法一:依据ASCII码转换,GB2312库对多音字也无能为力. GB2312标准共收录6763个汉字,不在范围内的汉字是无法转换.如:中国前总理朱镕基的"镕"字. GB2312中 ...
- android 68 单元测试
package com.itheima.junit; import android.os.Bundle; import android.app.Activity; import android.vie ...
- GCC内嵌汇编
http://blog.csdn.net/mydo/article/details/8279924
- Eclipse将项目部署tomcat的webapps目录
Eclipse将项目部署tomcat的webapps目录 >>>>>>>>>>>>>>>>>& ...
- 当winform窗体的Bordestyle设置为None时,鼠标可以拖动窗体的办法
方法一: 1 2015-07-11 16:05:35 Point formPoint;//记录窗体的位置 private void Form1_MouseDown(object sender, Mou ...
- HTML 转义字符
在HTML中,一个包含特殊字符(如<>&)的字符串,要显示在页面上,由于添加到文本节点时会被认为是HTML的标签结构,造成一些错误,因此,要将这些特殊字符进行转义. 例如在< ...
- asp.net 调用前台JS调用后台,后台掉前台JS
C#前台js调用后台代码前台js<script type="text/javascript" language="javascript"> func ...
- java中时间差计算
public class Utill { public String TimeString(Date currentTime, Date beginTime){ /*默认为毫秒,除以1000是为了转换 ...
- 第一节 WCF概述
主要内容: 1.什么是WCF? 2.WCF的背景介绍. 引例:(WCF用来解决什么事情) 一家汽车租赁公司决定创建一个新的应用程序,用于汽车预定 • 该租车预定应用程序的创建者知道,应用程序所实现的业 ...