# [cf115E]Linear Kingdom Races

1：不选，f[i]=f[i-1]

2:选，设连续往前一直选到第j+1条（0<=j<i）,则f[i]=f[j]-cost(j+1,i)+pay(j+1,i)

(cost(j+1,i)表示从j+1到i的赛道全部修复的所需付费,即cost[j+1]+cost[j+2]+...+cost[i]，pay(j+1,i)表示所有被完全包含在区间[j+1,i]内的比赛赚的钱总和)

f[i]=max{f[i-1],f[j]-cost(j+1,i)+pay(j+1,i)} (0<=j<i)

（没学过线段树优化dp的可以看下面这一段来入门）

cf上似乎没开边界检查？算术上溢的时候自然溢出了。

code:

  1 program cf115E;
2 type competition=record lb,rb,p:longint; end;
3 var tree:array[0..600000] of record flag,max:int64; end;
4     com:array[0..200010] of competition;
5     cost:array[0..200010] of longint;
6     f:array[0..200010] of int64;
7     i,j,n,m:longint;
8     ans:int64;
9 procedure sort(l,r:longint);
10 var i,j,x:longint;
11     t:competition;
12 begin
13   i:=l; j:=r; x:=com[(l+r)shr 1].rb;
14   repeat
15     while com[i].rb<x do inc(i);
16     while com[j].rb>x do dec(j);
17     if i<=j then
18       begin
19         t:=com[i];
20         com[i]:=com[j];
21         com[j]:=t;
22         inc(i);
23         dec(j);
24       end;
25   until i>j;
26   if i<r then sort(i,r);
27   if j>l then sort(l,j);
28 end;
29 function maxf(a,b:int64):int64;
30 begin
31   if a>b then exit(a) else exit(b);
32 end;
33 procedure pushdown(x:longint);
34 begin
35   tree[x+x].max:=tree[x+x].max+tree[x].flag;
36   tree[x+x+1].max:=tree[x+x+1].max+tree[x].flag;
37   tree[x+x].flag:=tree[x+x].flag+tree[x].flag;
38   tree[x+x+1].flag:=tree[x+x+1].flag+tree[x].flag;
39   tree[x].flag:=0;
40 end;
41 procedure edit_len(x,nowl,nowr,l,r,p:longint);
42 var mid:longint;
43 begin
44   if (nowr<l)or(nowl>r) then exit;
45   if (l<=nowl)and(nowr<=r) then
46     begin
47       with  tree[x] do
48         begin
49           flag:=flag+p;
50           max:=max+p;
51         end;
52       exit;
53     end;
54   pushdown(x);
55   mid:=(nowl+nowr)shr 1;
56   edit_len(x+x,nowl,mid,l,r,p);
57   edit_len(x+x+1,mid+1,nowr,l,r,p);
58   tree[x].max:=maxf(tree[x+x].max,tree[x+x+1].max);
59 end;
60 procedure edit_point(x,nowl,nowr,posi:longint;p:int64);
61 var mid:longint;
62 begin
63   if nowl=nowr then
64     begin
65       tree[x].flag:=p;
66       tree[x].max:=p;
67       exit;
68     end;
69   pushdown(x);
70   mid:=(nowl+nowr) shr 1;
71   if posi<=mid then edit_point(x+x,nowl,mid,posi,p)
72     else edit_point(x+x+1,mid+1,nowr,posi,p);
73   tree[x].max:=maxf(tree[x+x].max,tree[x+x+1].max);
74 end;
75 function find(x,nowl,nowr,l,r:longint):int64;
76 var mid:longint;
77 begin
78   if (nowr<l)or(nowl>r) then exit(-maxlongint);
79   if (nowl>=l)and(nowr<=r) then exit(tree[x].max);
80   pushdown(x);
81   mid:=(nowl+nowr) shr 1;
82   find:=maxf(find(x+x,nowl,mid,l,r),find(x+x+1,mid+1,nowr,l,r));
83 end;
84 begin
86   for i:=1 to n do readln(cost[i]);
87   for i:=1 to m do with com[i] do readln(lb,rb,p);
88   sort(1,m);
89   f[0]:=0;
90   ans:=0;
91   j:=1;
92   for i:=1 to n do
93     begin
94       while com[j].rb=i do
95         begin
96           edit_len(1,0,n,0,com[j].lb-1,com[j].p);
97           inc(j);
98         end;
99       edit_len(1,0,n,0,i-1,-cost[i]);
100       f[i]:=find(1,0,n,0,i-1);
101       if f[i-1]>f[i] then f[i]:=f[i-1];
102       edit_point(1,0,n,i,f[i]);
103       if f[i]>ans then ans:=f[i];
104     end;
105   writeln(f[n]);
106 end.

posted @ 2016-10-15 23:03 lkmcfj 阅读(...) 评论(...) 编辑 收藏