线段树之单点更新,区域求和

今天在coreforces上做的一题

E. DZY Loves Fibonacci Numbers
time limit per test

4 seconds

memory limit per test

256 megabytes

input

standard input

output

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 mqueries, each query has one of the two types:

  1. 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.
  2. 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.

Sample test(s)
input
4 4
1 2 3 4
1 1 4
2 1 4
1 2 4
2 1 3

output
17
12

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去加到每个节点,求区域的和

代码如下:


#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;const int MAXNODE = 2097152; // == (1 << 21) - 1  depth:21
const int MAXS = 300003;
struct SOILD{int left,right; // 数组模拟满二叉树, 区间 [left,right]long value;
}Soldier[MAXNODE];
long fib[300005];
int father[MAXS]; // 存每一个士兵的父结点void BuildTree(int i,int left,int right,int devalue){ // 初始值为0Soldier[i].left = left;Soldier[i].right = right;Soldier[i].value = devalue;if (left == right){father[left] = i; // 可以瞬间知道第i个士兵的父节点是哪个return;}BuildTree(i*2, left, (int)floor((right+left)/2.0), 0);BuildTree(i*2+1, (int)floor((right+left)/2.0)+1, right, 0);
}void UpdataTree(int ri,int iKilln){ // 单点更新: 点p[i,i] 更新为iKilln (初始为0)if (ri == 1){Soldier[ri].value += iKilln;return;}Soldier[ri].value += iKilln; // iKilln 设为全局变量应该快一点UpdataTree(ri/2,iKilln);
}long res;
void Query(int i,int a,int b){ // [a,b]区间的和if (a == Soldier[i].left && b == Soldier[i].right){res += Soldier[i].value;return ;}if (a <= Soldier[i*2].right){ // 左端点小于右端点(几何含义:区间横跨过中点) 则区间需要分割if (b <= Soldier[i*2].right){Query(i*2, a, b); // 左边全包含}else{Query(i*2, a, Soldier[i*2].right); // 横跨取左}}if (b >= Soldier[i*2+1].left){if (a >= Soldier[i*2+1].left){Query(i*2+1, a, b); // 右边全包含}else{Query(i*2+1, Soldier[i*2+1].left, b); // 横跨取右}}
}int main(){int n_s,n_q;long iKilln,a,b;cin >> n_s >> n_q;BuildTree(1,1,n_s,0);fib[1]=1;fib[2]=1;for(int k2=3;k2<300005;k2++){fib[k2]=fib[k2-1]+fib[k2-2];}for (int ii = 1 ;ii <= n_s; ii++){ // 建树scanf("%d",&iKilln);  // iKilln 为第 i 个增加的杀敌数UpdataTree(father[ii],iKilln); // 瞬间找到士兵的结点序号}int order;for (int i = 1; i <= n_q; i++){scanf("%d%d%d",&order,&a,&b); // [a,b] ; a + kill b  if (order==2){res = 0;Query(1,a,b);printf("%d\n", res);}else{for(int kk=a;kk<=b;kk++)UpdataTree(father[kk],fib[kk-a+1]);}//for(int ttt=1;ttt<=n_s;ttt++)//  printf("%d;;",Soldier[father[ttt]].value);//  printf("\n");}return 0;
}

要取 long long/__int64;

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2014-07-14 00:06 france 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/france/p/4808782.html

线段树之单点更新,区域求和相关推荐

  1. hdu 1166 敌兵布阵(线段树之 单点更新+区间求和)

    敌兵布阵                                                                             Time Limit: 2000/10 ...

  2. HDUOJ---1754 I Hate It (线段树之单点更新查区间最大值)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  3. HDU 1394 Minimum Inversion Number(线段树的单点更新)

    点我看题目 题意 :给你一个数列,a1,a2,a3,a4.......an,然后可以求出逆序数,再把a1放到an后,可以得到一个新的逆序数,再把a2放到a1后边,,,,,,,依次下去,输出最小的那个逆 ...

  4. [ACM] hdu 1754 I Hate It (线段树,单点更新)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. 线段树(单点更新(模板)) 之 hdu 1166

    // [7/24/2014 Sjm] /* 第一道用线段树做的题,照着大神的代码风格写的,,就当作线段树单点更新的模板吧....(当年用树状数组做的:代码见这里) */ 1 #include < ...

  6. 【HDU - 1166】敌兵布阵 (线段树模板 单点更新+ 区间查询)

    题干: C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情 ...

  7. hdu 1754 I Hate It(线段树之 单点更新+区间最值)

    I Hate It                                                                             Time Limit: 90 ...

  8. Codeforces Beta Round #75 (Div. 1 Only) B. Queue 线段树。单点更新

    http://codeforces.com/problemset/problem/91/B 题意: 给你n个数,求得i 到n中小于a[i]的最右边的a[j],然后求a[i]到a[j]之间包含了多少个数 ...

  9. HUD2795 线段树(单点更新)

    题目中给出的h和w范围均大,其实n的最大范围才200000,所以我们建立的线段树大小为min(h,n),线段树的每一个节点包含一个变量c,记录当前区间内还剩下的可以put on的最大长度.插入一个数时 ...

最新文章

  1. rman备份脚本shell版
  2. 基于注册中心的Dubbo服务
  3. IDM出现输入用户名和密码不能下载解决方法
  4. 服务器装系统提示获取分区失败,u盘安装系统分区错误解决方法
  5. NSDictionary和NSMutableDictionary
  6. 【WinForm】自己写一个截图软件1 --注册全局热键
  7. 火狐可以使用广告终结者_使用Jupyter从终结者终止的地方重新启动脚本
  8. 计算机考试excel基础试题,计算机基础(Excel2010)试题及答案解析
  9. html5怎么把图片置顶,html/css如何让图片上下居中(居中垂直)?
  10. C#集成FastReport.Net并将模板保存到数据库
  11. Ubuntu 查看系统版本
  12. 数仓1.4 |业务数仓搭建| 拉链表| Presto
  13. win7网络不显示共享计算机,win7查找不到网络计算机怎么办_win7看不到网络计算机怎么解决-win7之家...
  14. 如何使用传统图像处理方法进行大米的计数和长轴方向标记
  15. 软件学院“SIdea”软件创意大赛
  16. 微价值:专访个人开发者800万用户之《系统清道夫》
  17. 最简单的基于FFmpeg的解码器-纯净版(不包含libavformat)
  18. Laradock 使用笔记
  19. jquery禁用右键、文本选择功能、复制的代码
  20. Say Hello to Integers(10分)

热门文章

  1. windows 找不到本地配置文件用临时配置文件让您登录
  2. matplotlib.pyplot
  3. Java学习总结(随笔)——利用JSON解析实现网络下载
  4. 为激励女工程师推出的编程盛宴
  5. Espcms 注册或登录提示Can not connect to MySQL server
  6. Scrum 大白话总结
  7. 压缩文本、字节或者文件的压缩辅助类-GZipHelper 欢迎收藏
  8. 使用Aop管理所有Valid结构bindingResult
  9. 一个新基民的感叹:人心不足蛇吞象
  10. oracle 删除已备份归档,通过RMAN联机全库备份,包括控制文件,归档日志文件,备份成功后,删除已备份的归档日志。...