码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-11-06 22:41:19      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:proc   roc   begin   之间   开始   type   i+1   end   区间   

题意:
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[k,k+1]到 dp[k,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.

 

 

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

标签:proc   roc   begin   之间   开始   type   i+1   end   区间   

原文地址:http://www.cnblogs.com/myx12345/p/6036416.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!