经典题,记录每个位置对应数下次出现的位置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.