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. 拓扑排序(Toposort)

    摘自:https://blog.csdn.net/qq_35644234/article/details/60578189 <图论算法> 1.拓扑排序的介绍 对一个有向无环图(Direct ...

  2. 《梦断代码Dreaming In Code》阅读笔记(一)

    第0章!干得漂亮! 这是我看到这本书冒出来的第一个想法.身为计算机系的学生,对于从0开始的任何事情,都感到格外亲切. 进入阅读之后,疑惑.惊讶.感叹渐渐取代了之前轻松的心情,原来做软件竟是攀越一座又一 ...

  3. Python实用技巧

    1.改变工作目录 import os os.chdir('C:/Users/Mr.Zhao') 2.搜索制定目录下的文件 1 import glob 2 glob.glob('C:/User/Mr.Z ...

  4. 软工实践Alpha冲刺(1/10)

    队名:我头发呢队 组长博客 作业博客 张杰(组长) 过去两天完成了哪些任务 查阅Python爬取音源的资料,如 Python3爬虫抓取网易云音乐热评实战 Python爬取高品质QQ音乐(2) 如何爬网 ...

  5. 刷ROM必備的clockworkmod recovery

    Desire HD 手機早早就 Root,前陣子也S-OFF 變成工程版的 HBOOT(ENG S-OFF),想要刷機的朋友一定常常聽人提起 clockworkmod recovery ,接下來就是安 ...

  6. bpf程序

    bpf都是怎么起作用的? 记得bpf之前是绑定在bpf bpf作用在哪里呀?

  7. 在a标签的href用户#name 的可以实现页面 上下跳转

  8. poj1474 Video Surveillance

    题意:求多边形的内核,即:在多边形内部找到某个点,使得从这个点能不受阻碍地看到多边形的所有位置. 只要能看到所有的边,就能看到所有的位置.那么如果我们能够在多边形的内部的点x看到某条边AB,这个点x一 ...

  9. POJ.1006 Biorhythms (拓展欧几里得+中国剩余定理)

    POJ.1006 Biorhythms (拓展欧几里得+中国剩余定理) 题意分析 不妨设日期为x,根据题意可以列出日期上的方程: 化简可得: 根据中国剩余定理求解即可. 代码总览 #include & ...

  10. Python3简单入门

    在Mac和Linux上运行Python时,请打开终端,然后运行python3 Mac OSX 正确地同时安装Python 2.7 和Python3:  http://www.jianshu.com/p ...