Description

There is a river, which contains n stones from left to right. These stones are magic, each
one has a magic number Ai which means if you stand on the ith stone, you can jump to (i +1)th stone, (i+2)th stone, ..., (i+Ai)th stone(when i+Ai > n, you can only reach as far as n), you want to calculate the number of ways to reach the nth stone.
Notice: you can not jump from right to left! 
 

Input

Input starts with an integer T(1 <= T <= 10), denoting the number of test cases. Each test case contains an integer n(1 <= n <= 105), denoting the number stones. Next line contains n integers Ai(1 <= Ai <= 108). 

Output

For each test case, print the number of way to reach the nth stone module 109+7. 

Sample Input

3
5
1 2 3 4 5
1
10
2
2 1

Sample Output

3
1
1 题意:给你n个数,对于ai表示可以跳到i+1,i+2,i+3 …i + ai的位置,问到达最后一个位置有几种方法。
思路:第一次接触线段树。由于转移的关系,刚开始想使用DP,但是需要转移的数是一个区间,后来想到因为修改的是一个区间的值,想到用树状数组,但是区间修改的操作好像很烦阿
   最终被告知是线段树。
 #include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#define nods(x) tree[x]
#define lefs(x) tree[x << 1]
#define rigs(x) tree[x << 1 | 1]
using namespace std; const int INF = 0x3f3f3f3f;
const int MAX = ;
const int MOD = 1e9 + ; struct segtree
{
int l, r, ans; //区间范围
int add; //懒惰标记
}tree[MAX << ]; //单点修改
void change(int &bep, int val)
{
bep += val;
bep = (bep % MOD + MOD) % MOD;
}
//父节点更新
void pushup(int pos)
{
change(nods(pos).ans, lefs(pos).ans + rigs(pos).ans);
}
//构造线段树
void build(int p, int l, int r)
{
nods(p).l = l;
nods(p).r = r;
nods(p).ans = nods(p).add = ;
if(l == r && l == )
nods(p).ans = ;
if(l == r)
return ; int mid = (l + r) >> ;
build( p << , l, mid );
build( p << | , mid + , r);
pushup(p);
}
//向下更新叶 通过延迟标记更新
void pushdown(int p)
{
if(nods(p).add)
{
change(lefs(p).add, nods(p).add);
change(rigs(p).add, nods(p).add);
change(lefs(p).ans, nods(p).add);
change(rigs(p).ans, nods(p).add);
nods(p).add = ;
}
}
//询问
int query(int p, int bor)
{
if(nods(p).l == nods(p).r)//递归到最小叶,直接返回
return nods(p).ans;
pushdown(p); //先应用标记 再查询 int mid = (nods(p).l + nods(p).r) >> ;
if(bor <= mid)
return query(p << , bor); //查询下一层左儿子
else return query(p << | , bor); //查询下一层右儿子
}
//区间修改
void update(int p, int l, int r, int val)
{
if(nods(p).l >= l && nods(p).r <= r) //完全包含
{
change(nods(p).add, val); //延迟标记
change(nods(p).ans, val); //更新该点
return ;
}
pushdown(p); //向下更新
int mid = (nods(p).l + nods(p).r) >> ;
if(r <= mid) //[l,r] 被包含于 [pl,mid]
update(p << , l, r , val);
else if(l > mid) //[l,r] 被包含于 [mid,pr]
update(p << | , l, r, val);
else //中间截断
{
update(p << , l, mid, val);
update(p << | , + mid, r, val);
}
pushup(p);
} int main()
{
int T, t;
int ans, ss, ee, n;
cin >> T;
while(T--)
{
scanf("%d", &n);
build(, , n);
for(int i = ; i <= n; i++)
{
scanf("%d", &t);
ss = i + ;
ee = min(i+t, n);
ans = query(, i);
if(i!=n)
update(, ss, ee, ans);
}
printf("%d\n", query(, n));
}
}


NOJ/HUST 1095 校赛 Just Go 线段树模板题的更多相关文章

  1. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  2. hdu1823(二维线段树模板题)

    hdu1823 题意 单点更新,求二维区间最值. 分析 二维线段树模板题. 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息. 一般一维线段树是切割某一可变区间直到满足所要查询 ...

  3. [POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]

    可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include &l ...

  4. HDU 1698 Just a Hook (线段树模板题-区间求和)

    Just a Hook In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of t ...

  5. UESTC - 1057 秋实大哥与花 线段树模板题

    http://acm.uestc.edu.cn/#/problem/show/1057 题意:给你n个数,q次操作,每次在l,r上加上x并输出此区间的sum 题解:线段树模板, #define _CR ...

  6. 2016多校8th 1008【线段树-神题】

    题意: T N M N个数 M个操作 一个数组A, 有3个操作 1 l r x,a[l]-a[r]都+x 2 l r,a[i]=sqrt(a[i]),l<=i<=r 3 l r,求和,a[ ...

  7. POJ - 3264 线段树模板题 询问区间最大最小值

    这是线段树的一个模板题,给出一串数字,然后询问区间的最大最小值. 这个其实很好办,只需把线段树的节点给出两个权值,一个是区间的最小值,一个是区间的最大值,初始化为负无穷和正无穷,然后通过不断地输入节点 ...

  8. 敌兵布阵 HDU - 1166 (树状数组模板题,线段树模板题)

    思路:就是树状数组的模板题,利用的就是单点更新和区间求和是树状数组的强项时间复杂度为m*log(n) 没想到自己以前把这道题当线段树的单点更新刷了. 树状数组: #include<iostrea ...

  9. zkw线段树模板题

    学了zkw线段树,觉得没什么必要刷专题的吧(切不动啊).. 那先放一个模板题吧(我绝不会和你说搬了一道树状数组模板题的!!!) 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加 ...

随机推荐

  1. cp的使用

    一.形式 cp [options] source1 source2 source3 .... directory 参数意义: 参数 意义 -i 当目标文件已存在时,会询问是否覆盖 -p 连同文件的属性 ...

  2. Java中抽象类也能实例化

    在Java中抽象类真的不能实例化么? 在学习的过程中,发现了一个问题,抽象类在没有实现所有的抽象方法前是不可以通过new来构建该对象的,但是抽象方法却是可以有自己的构造方法的.这样就把我搞糊涂了,既然 ...

  3. 20162328蔡文琛week03

    学号 2006-2007-2 <程序设计与数据结构>第X周学习总结 教材学习内容总结 在第三章,我学习到了更多有关于java.util包的知识.了解了多个引用变量可以指向同一个对象.而且J ...

  4. 软件工程课堂作业(二)续——升级完整版随机产生四则运算题目(C++)

    一.设计思想: 1.根据题目新设要求,我将它们分为两类:一类是用户输入数目,根据这个数目改变一系列后续问题:另一类是用户输入0或1,分情况解决问题. 2.针对这两类要求,具体设计思路已在上篇博文中写出 ...

  5. jspSmartUpload上传下载使用例子

    --------------------------------------------------------------------- ServletUpload.java 上传 package ...

  6. 《学习OpenCV》课后习题解答2

    题目:(P104) 创建一个拥有三个通道的二维字节类型矩阵,大小为100*100,并将所有值赋为0.通过函数cvPtr2D将指针指向中间的通道("绿色").以(20,5)与(40, ...

  7. 原生javascript自定义input[type=checkbox]效果

    2018年6月27日  更新 能用css3,就不用js 用纯css3实现样式重写 <!DOCTYPE html> <html lang="en"> < ...

  8. Android OCR文字识别 实时扫描手机号(极速扫描单行文本方案)

    身份证识别:https://github.com/wenchaosong/OCR_identify 遇到一个需求,要用手机扫描纸质面单,获取面单上的手机号,最后决定用tesseract这个开源OCR库 ...

  9. MVC 枚举 转 SelectListItem

    ViewBag.userlevel = new SelectList(Enum.GetNames(typeof(AdminLevels)),"", "", te ...

  10. ASP.NET MVC4中使用bootstrip模态框时弹不出的问题

    最近发现使用在MVC中使用bootstrip的模态框时弹不出来,但单独建立一HTML文件时可以弹出,说明代码没有问题,经过多次测试发现,在MVC的cshtml文件中添加上以下语句就能正常 @{ Lay ...