• 【CF675E】Trains and Statistic(贪心,DP,线段树优化)


    题意:
    a[i]表示从第i个车站可以一张票到第[i+1,a[i]]这些车站;
    p[i][j]表示从第i个车站到第j个车站的最少的票数,现在要求∑dp[i][j](1<=i<=n,i<j<=n);

    思路:从I开始走,在i+1到a[i]之间一定会到使a[j]最大的j,因为要使步数最小,接下来能走得更快
    区间询问最值用RMQ与线段树都可以
    dp[i]表示dp[i,i+1],dp[i,i+2]...dp[i,n]这些值的和
    dp[i]=dp[k]+(n-i)-(a[i]-k),k为[i+1,a[i]]中使a[k]最大的k
    n-i:有dp[i,i+1],dp[i,i+2]...dp[i,n]一共n-i个状态要从i走到k
    -(a[i]-k):dp[i,k+1]到 dp[i,a[i]]长度与之前相比没有变化
     1 type ok=record
     2          s:int64;
     3          a:longint;
     4         end;
     5 
     6 const oo=1000000000000000;
     7 
     8 var dp:array[0..100000]of int64;
     9     a:array[1..100000]of longint;
    10     tree:array[1..400000]of ok;
    11     n,i,k:longint;
    12     ans:int64;
    13 
    14 procedure pushup(p:longint);
    15 begin
    16  if tree[p<<1].s>tree[p].s then tree[p]:=tree[p<<1];
    17  if tree[p<<1+1].s>tree[p].s then tree[p]:=tree[p<<1+1];
    18 end;
    19 
    20 procedure build(l,r,p:longint);
    21 var mid:longint;
    22 begin
    23  tree[p].s:=a[l];
    24  tree[p].a:=l;
    25  if l=r then exit;
    26  mid:=(l+r)>>1;
    27  build(l,mid,p<<1);
    28  build(mid+1,r,p<<1+1);
    29  pushup(p);
    30 end;
    31 
    32 function query(l,r,x,y,p:longint):ok;
    33 var mid:longint;
    34     t:int64;
    35     q,tmp:ok;
    36 
    37 begin
    38  if (l=x)and(r=y) then exit(tree[p]);
    39  mid:=(l+r)>>1;
    40  t:=0;
    41  if (x>=l)and(y<=mid) then
    42  begin
    43   q:=query(l,mid,x,y,p<<1);
    44   if q.s>t then begin t:=q.s; tmp:=q; end;
    45  end else
    46  if (x>mid)and(y<=r) then
    47  begin
    48   q:=query(mid+1,r,x,y,p<<1+1);
    49   if q.s>t then begin t:=q.s; tmp:=q; end;
    50  end else
    51  begin
    52   q:=query(l,mid,x,mid,p<<1);
    53   if q.s>t then begin t:=q.s; tmp:=q; end;
    54   q:=query(mid+1,r,mid+1,y,p<<1+1);
    55   if q.s>t then begin t:=q.s; tmp:=q; end;
    56  end;
    57  exit(tmp);
    58 end;
    59 
    60 begin
    61  //assign(input,'1.in'); reset(input);
    62  //assign(output,'1.out'); rewrite(output);
    63  readln(n);
    64  for i:=1 to n-1 do read(a[i]);
    65  a[n]:=n;
    66  build(1,n,1);
    67 
    68  for i:=n-1 downto 1 do
    69  begin
    70   k:=query(1,n,i+1,a[i],1).a;
    71   dp[i]:=dp[k]+(n-i)-(a[i]-k);
    72  end;
    73  for i:=1 to n do ans:=ans+dp[i];
    74  writeln(ans);
    75  //close(input);
    76  //close(output);
    77 end.
     
  • 相关阅读:
    6 原型模式
    10 观察者模式
    4 代理模式
    写错误日志
    C#事件的使用
    将int型数字转换成7位字符串,不足的时候,前面补0
    Excel 2010导数据到SQL SERVER 2008
    jquery checkbox
    修改注册表开启IE跨域访问功能
    存储过程一例
  • 原文地址:https://www.cnblogs.com/myx12345/p/6036416.html
Copyright © 2020-2023  润新知