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. 在线求助man page

    一.举例——输入“man date” 图1 图2 图3 二.man之概述 用于:命令的使用说明 用法:man 命令 man page:执行“man 命令”后,出现的屏幕界面 补:man是manual( ...

  2. Fafa and the Gates(模拟)

    Two neighboring kingdoms decided to build a wall between them with some gates to enable the citizens ...

  3. 【Linux】- Ubutnu UFW防火墙的简单设置

    ufw是一个主机端的iptables类防火墙配置工具,比较容易上手.一般桌面应用使用ufw已经可以满足要求了. 安装方法 sudo apt-get install ufw 使用方法 1.启用: sud ...

  4. MyBatis事务管理机制

    MyBatis作为Java语言的数据库框架,对数据库的事务管理是其非常重要的一个方面.   本文将讲述MyBatis的事务管理的实现机制,首先介绍MyBatis的事务Transaction的接口设计以 ...

  5. 第一章 Spring 概述

    Spring框架的生态,已经成了JavaWeb开发的事实标准 以IOC与AOP为基础,提供了一整套JavaWeb的开发解决方案 在需要引入功能前,先看看有没有Spring的实现,或者其他框架,看看能否 ...

  6. Matlab中fspecial的用法【转】

    Fspecial函数用于创建预定义的滤波算子,其语法格式为:h = fspecial(type)h = fspecial(type,parameters,sigma) 参数type制定算子类型,par ...

  7. 只要访问的地址匹配cookie的地址时候 发送request请求时候 会携带上该cookie

    只要访问的地址匹配cookie的地址时候 发送request请求时候 会携带上该cookie

  8. Python 开篇及第一个Python程序

    本节内容 python 简单介绍 python 2.x 或者python 3.x python 安装 第一个python程序 一.python简单介绍 python的创始人为吉多.范罗苏姆(Guido ...

  9. Oracle数据库表被锁定以及去除方式

    select t2.username, t2.sid, t2.serial#, t3.object_name, t2.OSUSER, t2.MACHINE, t2.PROGRAM, t2.LOGON_ ...

  10. 【题解】CF#983 E-NN country

    首先,我们从 u -> v 有一个明显的贪心,即能向上跳的时候尽量向深度最浅的节点跳.这个我们可以用树上倍增来维护.我们可以认为 u 贪心向上跳后不超过 lca 能跳到 u' 的位置, v 跳到 ...