鏖戰字串

2021-07-24 14:30:25 字數 3376 閱讀 3960

題目描述

abwad在nbc即將完成她的程式的時候,急中生智拔掉了她電腦的電源線,爭取到了寶貴的時間。作為著名**《論ctrl-c與ctrl-v在資訊學競賽中的應用》的作者,他巧妙地使用了這種上古秘術,順利扳回一城。

在決勝局中,abwad決定和nbc鏖戰字串,比的是誰能更快地將乙個「量子態的字串」刪除。「量子態的字串」的每個字元都有乙個刪除難度dif[i]。「量子態的字串」非常頑固,只能先分割成若干個子串,然後再通過以下兩種方式刪除:

1、假設子串的所有字元的刪除難度之和為x,消耗a*x^2+b的時間可以將子串扔進**站。

2、若子串中出現次數最多的字元出現的次數不少於l次且不多於r次,那麼採用「量子態的py自動機」演算法可以消耗c*x+d的時間將子串扔進**站。

abwad自然知道最少用多少時間就能將字串刪去,因此,他希望你求出刪去每個字首[1,i]的最少用時。

輸入 第一行七個整數n,a,b,c,d,l,r,其中n表示字串的長度

第二行一行乙個長度為n的字串

第三行一行n個整數,表示每個字元的刪除難度dif[i]

輸出 n行,每行乙個整數ans,表示刪去字首[1,i]最短的時間

樣例輸入

5 1 3 1 5 1 1

abwad

1 1 1 1 1

樣例輸出

4 7

8 12

13提示

【樣例1解釋】

以字首[1,n]為例,將串分為a、bwad兩個子串,用方法1刪去第乙個子串,用方法2刪去第二個子串,用時1*1+3+1*4+5=13

對於所有的資料,滿足n≤100000,1≤a,b,c,d≤233,1≤l,r≤n,dif[i]≤50,所有字元由小寫字母組成。

【後記】

在abwad和nbc同時將最後乙個子串刪去時,乙個帶著黑色方框眼鏡,方臉,穿著高腰褲的長者,乘著聖潔的祥雲,飛進了yyhs的機房。在他偉大的思想的啟發下,abwad和nbc終於放下了對名利的追逐,找到了人生的意義——吃吃吃。從此,他們過上了幸福快樂的生活……

對於方式一,顯然是斜率優化。至於方案二,dp[i]=min,變形可得,dp[i]=dp[i]*c+d+min(dp[j]-sum[j]*c)。由於方案二需要滿足「最多的字元出現的次數不少於l次且不多於r」,所以必定是在乙個區間內轉移的,所以我們維護這樣乙個區間的單調佇列,記錄min(dp[j]-sum[j]*c),這樣就可以轉移了。

var

n,l,r,i,j,markl,st,ed,markr,sta,eda:longint;

a,b,c,d,x:int64;

sum,f,dif,q,p:array[0..500022] of int64;

s:array[0..500022] of char;

cntl,cntr:array['a'..'z'] of longint;

function

min(a,b:int64):int64;

begin

if athen

exit(a) else

exit(b);

end;

function

judge1

(i,j,k:longint):boolean;

begin

if f[j]+a*sqr(sum[j])-f[k]-a*sqr(sum[k])<=2*a*sum[i]*(sum[j]-sum[k]) then

exit(true)

else

exit(false);

end;

function

judge2

(i,j,k:longint):boolean;

varaa,b,c,d:int64;

begin

aa:=f[i]+a*sqr(sum[i])-f[j]-a*sqr(sum[j]);

b:=(sum[i]-sum[j]);

c:=f[j]+a*sqr(sum[j])-f[k]-a*sqr(sum[k]);

d:=(sum[j]-sum[k]);

if aa*d<=b*c then

exit(true)

else

exit(false);

end;

begin

readln(n,a,b,c,d,l,r);

for i:=1

to n do

read(s[i]);

readln;

for i:=1

to n do

begin

read(dif[i]);

sum[i]:=sum[i-1]+dif[i];

end;

st:=1;

ed:=1;

sta:=1;

eda:=0;

markl:=1;

markr:=0;

for i:=1

to n do

begin

while (stand(judge1(i,q[st+1],q[st])) do st:=st+1;

f[i]:=f[q[st]]+b+a*sqr(sum[i]-sum[q[st]]);

inc(cntl[s[i]]);

inc(cntr[s[i]]);

while cntl[s[i]]>r do

begin

dec(cntl[s[markl]]);

markl:=markl+1;

while (sta<=eda)and(p[sta]+1

do inc(sta);

end;

while cntr[s[i]]>=l do

begin

if markr>0

then

begin

dec(cntr[s[markr]]);

if cntr[s[i]]then

begin

inc(cntr[s[markr]]);

break;

end;

end;

while (sta<=eda)and(f[markr]-sum[markr]*c<=f[p[eda]]-sum[p[eda]]*c) do dec(eda);

eda:=eda+1;

p[eda]:=markr;

markr:=markr+1;

end;

if sta<=eda then f[i]:=min(f[i],f[p[sta]]+d+(sum[i]-sum[p[sta]])*c);

writeln(f[i]);

while (stand(judge2(i,q[ed],q[ed-1])) do ed:=ed-1;

ed:=ed+1;

q[ed]:=i;

end;

end.

鏖戰字串

鏖戰字串 題目描述 abwad在nbc即將完成她的程式的時候,急中生智拔掉了她電腦的電源線,爭取到了寶貴的時間。作為著名 論ctrl c與ctrl v在資訊學競賽中的應用 的作者,他巧妙地使用了這種上古秘術,順利扳回一城。在決勝局中,abwad決定和nbc鏖戰字串,比的是誰能更快地將乙個 量子態的字...

ORACLE in 字串,字串,字串

因為傳進來的引數是 字串,字串,字串,要實現in 字串,字串,字串 select from htl price p where p.hotel id 30073328 and p.able sale date between to date 2009 03 27 yyyy mm dd and to ...

字串,字串陣列,字串指標!!

字串 字元陣列實際上是一系列字元的集合,也就是 字串 string 字串陣列 在c語言中,沒有專門的字串變數,沒有string型別,通常就用乙個字元陣列來存放乙個字串。c語言規定,可以將字串直接賦值給字元陣列 在c語言中,字串總是以 0 作為串的結束符。上面的兩個字串,編譯器已經在末尾自動新增了 0...