字串函式

2021-08-07 23:32:06 字數 2400 閱讀 4701

【noip2012模擬8.7】字串函式 (standard io)

time limits: 1000 ms memory limits: 65536 kb detailed limits

description

兩個等長的由大寫英文本母構成的字串a和b,從a中選擇連續子串x,從b中選出連續子串y。

定義函式f(x,y)為滿足條件xi=yi(1<=i<=|x|)的i的個數,計算f(x,y)的數學期望。(|x|=|y|)

input

第一行輸入n(1<=n<=2*10^5),表示a和b的長度

第二行輸入字串a

第三行輸入字串b

output

輸出乙個實數表示f(x,y)的期望,如果你的答案與正確答案相差不超過10^-6則認為是正確的。(保留6位)

sample input

2 ab

basample output

0.400000

data constraint

hint

考慮第乙個樣例,x,y的選擇有5種情況分別是(「a」,」b」),(「a」,」a」),(「b」,」b」),(「b」,」a」),(「ab」,」ba」)其中,第2對和第3對所對應的f(x,y)等於1,其他都是0,由於選擇每一對的概率都是1/5,所以f(x,y)的期望為1/5*0+1/5*1+1/5*1+1/5*0+1/5*0=2/5=0.4

對於10%的資料,可以o(n^3).列舉兩字串的開頭,列舉字串的長度。o(n^3).

對於60%的資料,可以o(n^2).我們可以用數學的方法,在找到兩個相同的字元後直接算出答案。將兩個字元所在的位置對齊。講兩個字串分別分出兩個部分。乙個左邊乙個右邊。先算出兩個字串的左邊的最小值,再算出兩個字串的右邊的最小值。右邊的界限是一定在右邊的最小值中的。左邊的界限是一定在左邊的最小值中。所以方法為左邊的數*右邊的數。(包含當前數)。這樣就能完成o(n^2)的演算法了。很好實現。

對於100%的資料,可以o(n*26),最大的複雜度在算字首和中。我們發現在第乙個字串中找到乙個字元,這個字元將整個第二個字串分成兩個部分。在第二個部分的字元中,左邊的數一定要大於當前找到的字元的位置的左邊的數;右邊的數一定要小於當前找到的字元的位置的右邊的數。所以,在第二部分的字元中,左邊的數乘上右邊的所有與其相同的字元的位置的右邊的數的和。所以右邊的所有與其相同的字元的位置的右邊的數的和可以用乙個字首和來預處理。如果在當前找到在字元的位置的右邊,那麼第二個字串的第一部分的左邊的數一定比當前的字元的位置的左邊要小,右邊的數反之。因此,也可以像處理第一部分的字元一樣,用字首和預處理出來。那麼ac就非常容易得到了。

var

n,p,l,r,ans,min,s,o,total:int64;

h:array['a'..'z'] of longint;

f,f2:array['a'..'z',0.

.200000] of longint;

i,j:longint;

ch:char;

st1,st2:ansistring;

begin

readln(n);

readln(st1);

readln(st2);

for i:=1

to length(st2) do

begin

for ch:='a'

to'z'

dobegin

if st2[i]=ch then

begin

f[st2[i],i]:=f[st2[i],i-1]+n-i+1;

endelse

begin

f[ch,i]:=f[ch,i-1];

end;

end;

end;

for i:=1

to length(st2) do

begin

for ch:='a'

to'z'

dobegin

if st2[i]=ch then

begin

f2[st2[i],i]:=f2[st2[i],i-1]+i;

endelse

begin

f2[ch,i]:=f2[ch,i-1];

end;

end;

end;

for i:=1

to n do

begin

s:=s+i*i;

end;

for i:=1

to length(st1) do

begin

total:=total+(f[st1[i],n]-f[st1[i],i-1])*(i);

total:=total+(f2[st1[i],i-1])*(n-i+1);

end;

writeln(total/s:0:6);

end.

字串和字串函式

字元輸入輸出 getchar putchar ch getchar putchar ch 字串函式 字串輸入 建立儲存空間 接受字串輸入首先需要建立乙個空間來存放輸入的字串。char name scanf s name 上述的用法可能會導致程式異常終止。使用字串陣列 可以避免上述問題 char na...

字串和字串函式

1.字串字面量 字串常量 用雙引號括起來的內容稱為字串字面量,也叫字串常量。字串常量屬於靜態儲存類別,這說明如果在函式中使用字串常量,該字串只會被儲存一次,在整個程式的生命期內存在,計時函式被呼叫多次。用雙引號括起來的內容被視為指向該字串儲存位置的指標。hello 中的 hello 類似於乙個陣列名...

字串函式

1 獲取字串的長度 length 2 判斷字串的字首或字尾與已知字串是否相同 字首 startswith string s 字尾 endswith string s 3 比較兩個字串 equals string s 4 把字串轉化為相應的數值 int型 integer.parseint 字串 lon...