bzoj3747

经典题,记录每个位置对应数下次出现的位置next[i]

每个位置维护当前左端点下到这个位置的和

随着左端点的右移一位到i+1,对[i+1,next[i]-1] 的影响是-a[i], [next[i],next[next[i]]-1]的影响是a[i]

线段树维护,pascal过不去系列

UPD:现在时限开大能过去了

 1 var lazy,tree:array[0..1000010*4] of int64;
 2     s:array[0..1000010] of int64;
 3     next,last,w,a:array[0..1000010] of longint;
 4     i,n,m:longint;
 5     ans:int64;
 6 
 7 function max(a,b:int64):int64;
 8   begin
 9     if a>b then exit(a) else exit(b);
10   end;
11 
12 procedure ins(i:longint;z:int64);
13   begin
14     tree[i]:=tree[i]+z;
15     lazy[i]:=lazy[i]+z;
16   end;
17 
18 procedure push(i:longint);
19   begin
20     ins(i*2,lazy[i]);
21     ins(i*2+1,lazy[i]);
22     lazy[i]:=0;
23   end;
24 
25 procedure add(i,l,r,x,y,z:longint);
26   var m:longint;
27   begin
28     if (x<=l) and (y>=r) then ins(i,z)
29     else begin
30       m:=(l+r) shr 1;
31       if lazy[i]<>0 then push(i);
32       if x<=m then add(i*2,l,m,x,y,z);
33       if y>m then add(i*2+1,m+1,r,x,y,z);
34       tree[i]:=max(tree[i*2],tree[i*2+1]);
35     end;
36   end;
37 
38 begin
39  
40   readln(n,m);
41   for i:=1 to n do
42     read(a[i]);
43   for i:=1 to m do
44   begin
45     read(w[i]);
46     last[i]:=n+1;
47   end;
48   for i:=n downto 1 do
49   begin
50     if last[a[i]]=n+1 then s[i]:=s[i+1]+w[a[i]]
51     else s[i]:=s[i+1];
52     next[i]:=last[a[i]];
53     last[a[i]]:=i;
54   end;
55   for i:=1 to m do
56     if last[i]>0 then add(1,1,n,last[i],next[last[i]]-1,w[i]);
57 
58   for i:=1 to n do
59   begin
60     if s[i]<=ans then break;
61     ans:=max(ans,tree[1]);
62     add(1,1,n,i,next[i]-1,-w[a[i]]);
63     if next[i]<=n then add(1,1,n,next[i],next[next[i]]-1,w[a[i]]);
64   end;
65   writeln(ans);
66 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4590875.html