題目名稱:奇怪的字串
檔名稱: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 代...