ISIJ 2018 奇怪的字串

2021-08-24 18:07:13 字數 2699 閱讀 3605

題目名稱:奇怪的字串

檔名稱:strange.in / strange.out

題目描述

考慮字串 s 僅由小寫字母組成,例如 「abba」。定義 w(s) 為 s 所有本質不同的連續子串的集合,例如 w(「abba」) = 。定義 y(s) 為 s 所有本質不同的非連續子串的集合,例如 y(「abba」) = w(「abba」) ∪ ,顯然 w(s) 是 y(s) 的子集。

對於一些奇怪的字串 s 滿足 w(s) = y(s),例如 「abba」 就不是奇怪的,但 「abb」 是奇怪的因為 w(s) = y(s) = 。現在小明有乙個字串 s,請你求出 w(s) 中有多少個字串是奇怪的?

注意:集合中的所有元素互不相同

限制1s 256m

1≤|s|≤ 200,000

輸入格式

乙個字串 s

輸出格式

乙個整數,表示 w(s) 中有多少個字串是奇怪的

輸入樣例

abba

輸出樣例

樣例解釋

abba 的所有連續子串中,除了 abba 以外都是 」 奇怪的 「

分析呃,畫個圖體會一下:

如果我想要證明,區間[l,r]不是奇怪的,我們可以證明[l,r]有乙個非連續的新子串。

如上圖,你剛掃到了x點,x的左邊是a,右邊是b。如果在x左邊,有乙個非a(並不是全是a)的串,那麼將它和x接起來,你就可以得到乙個在連續的情況下死都得不到的新序列。右邊同理。

將結論推廣,我們可以得到,如果區間不是奇怪的,那麼這個區間從左往右掃至少有三段字串(規定每串字串中字元都相同)。反推之,如果這個區間至多只有兩段字串,則區間一定是奇怪的。(必要且充分)

這時我們友好的發現,奇怪的子串只有兩種,aa型或者ab型,注意字串集合中元素不會重複出現。首先aa型非常好做,分別統計從』a』到』z』每種字串的最長,在加起來就得到了aa型的所有子串。

for(long

long i=1;i<=n;)

for(int i=0;i<26;i++)

ans+=length[i];

ab型由於考慮到重複統計,且有兩維,不能直接只取最大值。【例子(1,3)(3,1)(2,2)】我們考慮先開乙個vector將所有二元組(區域性最大)先存起來。

struct node;

vector

a[26][26];//兩維的vector

vector

::iterator iv;//懶人象徵(迭代器)

long

long i=1,j,ml,mr,l,r;

ml=s[1],l=1;

while(s[i]==s[i+1])i++,l++;

while(i1;mr=s[j];r=1;

while(j1]) j++,r++;

a[ml-'a'][mr-'a'].push_back((node));

i=j;l=r;ml=mr;

}

考慮二元組的計算,我們可以把它們看成乙個個矩形,用掃瞄線求矩形面積並。

鑑於掃瞄線的**量,我們開始思考優化方案,首先的我們想到,所有的橫座標都是從1到」長度「。可以用乙個平衡樹代替線段樹,每次插入或刪除乙個值。查詢出最大值,即為當前線段的長。平衡樹可以用stl的set

上述優化可以減少**量但不能優化時間,我們再介紹中更強的優化,簡潔好寫而且常數比前兩種小很多。

bool cmp(node x,node y)

void calc(int x,int y)}}

可否有些頭緒?我們先按左邊區間的長度排序,使得一側長度單調遞減,再判斷右側區間長度如果小於之前的最大長度。則一定被之前的某個區間包含過,不需要再計算。長度更長,則將超過最大長度的部分乘上自身的左側區間,更新最大值。

完整**如下:

#include

using

namespace

std;

const

int maxn=201000;

struct node;

vector

a[26][26];

vector

::iterator iv;

long

long n;

long

long length[26];

char s[maxn];

long

long ans=0;

void init());

i=j;l=r;ml=mr;

}return ;

}bool cmp(node x,node y)

void calc(int x,int y)

}}int main()

for(int i=0;i<26;i++)

ans+=length[i];

init();

for(int i=0;i<26;i++)

for(int j=0;j<26;j++)

if(a[i][j].size()>0)

calc(i,j);

printf("%lld\n",ans);

return

0;}

NOIP 模擬題 奇怪的字串

題目描述 有一天,小 a 的女票為了讓小 a 證明他對她的忠誠,要求小 a 生成乙個長度 為 n 的 全由小寫英文本母構成的字串,只能使用 k 種字母。要求滿足 字串中相鄰的兩個字母不能相同。必須出現恰好 k 種不同的字母。這樣的合法字串可能有很多,小 a 的女票要求小 a 輸出字典序最小的那個。小...

醜帥的 Perl 奇怪的字串

看上去很久都沒有寫部落格了。其中有兩個原因,第一是實在沒有時間 無奈 第二是感覺沒有碰到需要寫下來的東西,今天碰到 perl 中的字串標量,讓我覺得有寫下來的必要。都說 perl 醜,寫出來的 幾個月後自己都不認識,在 perl 中,確實有許多奇奇怪怪的語法,比如 perl 中字串與數字標量之間的隱...

2018 校招 字串距離

題目描述 給出兩個相同長度的由字元 a 和 b 構成的字串,定義它們的距離為對應位置不同的字元的數量。如串 aab 與串 aba 的距離為 2 串 ba 與串 aa 的距離為 1 串 baa 和串 baa 的距離為 0。下面給出兩個字串 s 與 t,其中 s 的長度不小於 t 的長度。我們用 s 代...