題目描述
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...