• 【CF407B】Long Path


    有个人进入一个迷宫,这个迷宫共有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])又回到这个点的时间
    而题目又有限制条件:(1leq 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
    ",(ans[n+1]+mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    DOM、Window对象操作
    JavaScript基础
    关于样式表的两个练习
    css样式表
    表单
    HTML的格式、内容容器、表格标签
    C#部分的总结
    Android自定义View之音频条形图
    String, StringBuilder, StringBuffer问题
    详解Java中ArrayList、Vector、LinkedList三者的异同点(转)
  • 原文地址:https://www.cnblogs.com/tqr06/p/11811578.html
Copyright © 2020-2023  润新知