贪心,递推,线段树,$RMQ$。

假设我们记$ans[i]$是以$i$点为起点对答案的贡献,那么答案就是$\sum\limits_{i = 1}^n {ans[i]}$。

$ans[i]$怎么计算呢?

首先,$[i+1,a[i]]$区间上肯定都是$1$(即上图紫线)。

然后在$[i+1,a[i]]$上找到一个$tmp$,使得$tmp$点能够达到的最右端是$[i+1,a[i]]$中最大的,那么$[a[i]+1,a[tmp]]$肯定都是2(即上图绿线)。

然后在$[a[i]+1,a[tmp]]$找一个$tmp2$......依次下去,计算出以$i$为起点对答案的贡献。

但是这样做复杂度太高,需要进行优化。

如果我们知道了$ans[tmp]$,那么就可以$O(1)$知道$ans[i]$,递推一下就可以了。

反过来想,如果我们想知道$ans[i]$,也就是要找到$tmp$,然后从$ans[tmp]$转移过来。

找$tmp$的话可以用线段树,也可以用$RMQ$预处理一下。

$RMQ$:

  1. #pragma comment(linker, "/STACK:1024000000,1024000000")
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<algorithm>
  6. #include<vector>
  7. #include<map>
  8. #include<set>
  9. #include<queue>
  10. #include<stack>
  11. #include<iostream>
  12. using namespace std;
  13. typedef long long LL;
  14. const double pi=acos(-1.0),eps=1e-;
  15. void File()
  16. {
  17. freopen("D:\\in.txt","r",stdin);
  18. freopen("D:\\out.txt","w",stdout);
  19. }
  20. template <class T>
  21. inline void read(T &x)
  22. {
  23. char c=getchar(); x=;
  24. while(!isdigit(c)) c=getchar();
  25. while(isdigit(c)) {x=x*+c-''; c=getchar();}
  26. }
  27.  
  28. const int maxn=;
  29. int a[maxn],n,tmp,dp[maxn][];
  30. LL ans[maxn];
  31.  
  32. void RMQ_init()
  33. {
  34. for(int i=;i<n;i++) dp[i][]=i;
  35. for(int j=;(<<j)<=n;j++)
  36. for(int i=;i+(<<j)-<n;i++){
  37. if(a[dp[i][j-]]>a[dp[i+(<<(j-))][j-]]) dp[i][j]=dp[i][j-];
  38. else dp[i][j]=dp[i+(<<(j-))][j-];
  39. }
  40. }
  41.  
  42. int RMQ(int L,int R)
  43. {
  44. int k=;
  45. while((<<(k+))<=R-L+) k++;
  46. if(a[dp[L][k]]>a[dp[R-(<<k)+][k]]) return dp[L][k];
  47. return dp[R-(<<k)+][k];
  48. }
  49.  
  50. int main()
  51. {
  52. scanf("%d",&n);
  53. for(int i=;i<n-;i++) scanf("%d",&a[i]),a[i]--;
  54. a[n-]=n-; RMQ_init(); ans[n-]=; LL d=;
  55. for(int i=n-;i>=;i--)
  56. {
  57. tmp=RMQ(i+,a[i]);
  58. ans[i]=ans[tmp]-(a[i]-tmp)+n--a[i]+a[i]-i;
  59. d=d+ans[i];
  60. }
  61. printf("%lld\n",d);
  62. return ;
  63. }

线段树:

  1. #pragma comment(linker, "/STACK:1024000000,1024000000")
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<algorithm>
  6. #include<vector>
  7. #include<map>
  8. #include<set>
  9. #include<queue>
  10. #include<stack>
  11. #include<iostream>
  12. using namespace std;
  13. typedef long long LL;
  14. const double pi=acos(-1.0),eps=1e-;
  15. void File()
  16. {
  17. freopen("D:\\in.txt","r",stdin);
  18. freopen("D:\\out.txt","w",stdout);
  19. }
  20. template <class T>
  21. inline void read(T &x)
  22. {
  23. char c=getchar(); x=;
  24. while(!isdigit(c)) c=getchar();
  25. while(isdigit(c)) {x=x*+c-''; c=getchar();}
  26. }
  27.  
  28. const int maxn=;
  29. int a[maxn],n,s[*maxn],M,tmp;
  30. LL ans[maxn];
  31.  
  32. void build(int l,int r,int rt)
  33. {
  34. if(l==r) { s[rt]=a[l]; return; }
  35. int m=(l+r)/; build(l,m,*rt); build(m+,r,*rt+);
  36. s[rt]=max(s[*rt],s[*rt+]);
  37. }
  38.  
  39. void f(int L,int R,int l,int r,int rt)
  40. {
  41. if(L<=l&&r<=R) { M=max(M,s[rt]); return; }
  42. int m=(l+r)/;
  43. if(L<=m) f(L,R,l,m,*rt);
  44. if(R>m) f(L,R,m+,r,*rt+);
  45. }
  46.  
  47. void force(int l,int r,int rt)
  48. {
  49. if(l==r) {tmp=l; return;}
  50. int m=(l+r)/;
  51. if(s[*rt]==M) force(l,m,*rt);
  52. else force(m+,r,*rt+);
  53. }
  54.  
  55. void h(int L,int R,int l,int r,int rt)
  56. {
  57. if(L<=l&&r<=R)
  58. {
  59. if(s[rt]<M) return;
  60. force(l,r,rt); return;
  61. }
  62. int m=(l+r)/;
  63. if(L<=m) h(L,R,l,m,*rt); if(tmp!=-) return;
  64. if(R>m) h(L,R,m+,r,*rt+); if(tmp!=-) return;
  65. }
  66.  
  67. int main()
  68. {
  69. scanf("%d",&n);
  70. for(int i=;i<=n-;i++) scanf("%d",&a[i]); a[n]=n;
  71. build(,n,); ans[n]=; LL d=;
  72. for(int i=n-;i>=;i--)
  73. {
  74. M=tmp=-; f(i+,a[i],,n,); h(i+,a[i],,n,);
  75. ans[i]=ans[tmp]-(a[i]-tmp)+n-a[i]+a[i]-i;
  76. d=d+ans[i];
  77. }
  78. printf("%lld\n",d);
  79. return ;
  80. }

CodeForces 675E Trains and Statistic的更多相关文章

  1. Codeforces 675E Trains and Statistic - 线段树 - 动态规划

    题目传送门 快速的vjudge通道 快速的Codeforces通道 题目大意 有$n$个火车站,第$i$个火车站出售第$i + 1$到第$a_{i}$个火车站的车票,特殊地,第$n$个火车站不出售车票 ...

  2. Codeforces 675E Trains and Statistic(DP + 贪心 + 线段树)

    题目大概说有n(<=10W)个车站,每个车站i卖到车站i+1...a[i]的票,p[i][j]表示从车站i到车站j所需买的最少车票数,求所有的p[i][j](i<j)的和. 好难,不会写. ...

  3. codeforces 675E Trains and Statistic 线段树+贪心统计

    分析:这个题刚看起来无从下手 但是我们可以先简化问题,首先可以固定起点i,求出i+1到n的最小距离 它可以到达的范围是[i+1,a[i]],贪心的想,我们希望换一次车可以到达的距离尽量远 即:找一个k ...

  4. codeforces E. Trains and Statistic(线段树+dp)

    题目链接:http://codeforces.com/contest/675/problem/E 题意:你可以从第 i 个车站到 [i + 1, a[i]] 之间的车站花一张票.p[i][j]表示从 ...

  5. CF 675E Trains and Statistic

    草稿和一些题解而已 因为指针太恶心了 所以query决定还是要试试自己yy一下 #include<cstdio> #include<cstring> #include<i ...

  6. codeforces 675E E. Trains and Statistic(线段树+dp)

    题目链接: E. Trains and Statistic time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  7. Codeforces Round #353 (Div. 2) E. Trains and Statistic dp 贪心

    E. Trains and Statistic 题目连接: http://www.codeforces.com/contest/675/problem/E Description Vasya comm ...

  8. 【34.54%】【codeforces 675E】Trains and Statistic

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  9. Codeforces Round #353 (Div. 2) E. Trains and Statistic 线段树+dp

    题目链接: http://www.codeforces.com/contest/675/problem/E 题意: 对于第i个站,它与i+1到a[i]的站有路相连,先在求所有站点i到站点j的最短距离之 ...

随机推荐

  1. 扩展Session机制

    分布式缓存扩展Session机制   为什么要把Session放在缓存中 Session是我们常用的状态保持的对象,它通常会生成一个唯一的SessionId以Cookie的方式存在浏览器端,而Sess ...

  2. require.js实践

    ASP.NET MVC应用require.js实践 这里有更好的阅读体验和及时的更新:http://pchou.info/javascript/asp.net/2013/11/10/527f6ec41 ...

  3. [转]Decrypt Any iOS Firmware on Mac, Windows, Linux

    source:http://www.ifans.com/forums/threads/decrypt-any-ios-firmware-on-mac-windows-linux.354206/ Dec ...

  4. [大整数乘法] java代码实现

    上一篇写的“[大整数乘法]分治算法的时间复杂度研究”,这一篇是基于上一篇思想的代码实现,以下是该文章的连接: http://www.cnblogs.com/McQueen1987/p/3348426. ...

  5. IOS开发之路三(XML解析之GDataXML的使用)

    最近再做一个项目需要用到xml的解析.今天查了一些资料自己做了一个小demo.纯OC没有界面.. 在IOS平台上进行XML文档的解析有很多种方法,在SDK里面有自带的解析方法,但是大多情况下都倾向于用 ...

  6. 增加窗体边框3D效果

    /// <summary> /// 增加窗体边框3D效果 /// </summary> /// <param name="e"></par ...

  7. EasyUI tree扩展获取实心节点

    <script type="text/javascript"> //扩展 获得tree 的实心节点 $(function(){ $.extend($.fn.tree.m ...

  8. 什么时候用spring

    论公司spring的滥用   这个公司每个项目用不同的一套开发框架,实在忍不住拿一个出来说说事.

  9. C#常用的数据格式转换

    用DataFormatString格式化GridView 在 GridView里面显示数据,要显示的数据有好多位小数,就想让它只显示两位小数,在delphi里,直接用DisplayFormat就行了, ...

  10. Java-调用抽象类中指定参数的构造方法

    abstract class person {  private String name;  private int age;  public person(String name,int age) ...