首页 > 其他 > 详细

【CF407B】Long Path

时间:2019-11-07 16:10:51      阅读:96      评论:0      收藏:0      [点我收藏+]
有个人进入一个迷宫,这个迷宫共有n+1个房间,编号从1~n+1
ta现在在第1个房间,需要到达第n+1个房间以出去。房间i有两个前进的门(来时的门不算)
第一扇门通向第i+1个房间,第二扇门通向第pi(1<=pi<=i)房间
为了不迷路,这个人每到达一个房间,就会给这个房间画一个标记
画完后如果这个房间的标记数为偶数个,ta就会选择这个房间第一扇门前进,否则选择第二扇门前进
 求这个人需要通过多少道门到达终点(即第n+1个房间),答案对1000000007取模

很简单的递推
\(ans[i]\)为第一次到i节点的时间

很显然,如果直接从前一个点走过来,有递推关系:
\[ans[i]+=ans[i-1]+1\]

但由于我们设的是第一次到达这个点的时间,所以还要算出从\(i-1\)号节点绕一大圈又回到\(i-1\)号点的时间:
\[ans[i]+=ans[i-1]+1-ans[fa[i-1]]\]

这个关系很好理解,就是从\(i-1\)绕一大圈到\(fa[i-1]\)又回到这个点的时间
而题目又有限制条件:\(1\leq fa[i]\leq i\),每一项只与前面的某些项有关
所以我们\(\Theta(n)\)递推一遍即可

代码:

#include<bits/stdc++.h>
#define mod 1000000007
#define N 1000005
using namespace std;

int n,a[N];
long long ans[N];

template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

int main()
{
    read(n);
    for(register int i=1;i<=n;++i) read(a[i]);
    for(register int i=2;i<=n+1;++i)
        ans[i]=((ans[i-1]+1)+(ans[i-1]+1)-ans[a[i-1]])%mod;
    printf("%lld\n",(ans[n+1]+mod)%mod);
    return 0;
}

【CF407B】Long Path

原文:https://www.cnblogs.com/tqr06/p/11811578.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!