SAM GDKOI2014 基因模式

2021-10-09 21:44:04 字數 2187 閱讀 3752

sa首先將t和si首尾相接連起來,每兩個串之間隔乙個未出現過的字元,求出字尾陣列及height陣列,即字尾陣列中相鄰兩個字尾的最長公共字首。然後o(n)掃瞄可得每個字尾i和在原t串中開始的每個字尾j最長的最長公共字首是多少,記為near[i],這樣字尾j即在字尾陣列中與字尾i最近的兩個在t中開始的字尾中的乙個。即。這樣我們就可以求出在sp中每個位置sp,q向後匹配最長near[i]長度能使在這段長度內任意的以sp,q開始的串都能在t中找到對應的子串。

現在我們已經滿足了在t串中有相應子串的條件,還需要滿足一定的奇偶性。用乙個四位的二進位制表示四種鹼基的奇偶性。對於每個si,我們做如下統計:用乙個0~15的陣列f表示從st到en區間內每種奇偶性出現了多少次。從前向後掃瞄,移動st和en使對於每個i有st=i及en=i+near[i]-1,注意到st和en只會向後移動,對於每個i可用16的時間掃面陣列統計滿足要求的。en=en+1時,是將原來統計到的所有以en-1結尾的串轉變為以en結尾,每個被統計到的串都在尾部加上了鹼基en,記是從陣列f轉移到f』, f』[i]=f[ix],表示異或,x表示鹼基en本身奇偶性,即x是乙個二的冪。此外還要f』[x]=f』[x]+1,即新增了乙個僅由en構成的串。st=st+1時,刪除了乙個從st一直到en的最長的串,直接在對應位置減一即可。

綜上,我們用o(nlog2n)的時間構建字尾陣列,再用o(16n)的時間掃瞄。你也可以用dc3把字尾陣列寫成o(n)的。這裡的n指的是所有字串的總長度。

sam可是出題人說本來不想讓上面的演算法過的,應該用字尾自動機。對t建字尾自動機,然後用每個si在字尾自動機上匹配,即可輕鬆地求出near。後面的掃瞄同上。這個演算法把構建字尾陣列的o(nlog2n)優化為o(4n),而且這裡的n不再是所有字串的總長度而是t的長度,速度會略有提公升。

#include

#define ll long long

using

namespace std;

const

int n=

2e5+

77,s=

1<<4;

int n,m,q;

char s[n]

,t[n]

,id[

128]

,yjy[4]

;namespace sam

sam[

(n <<1)

+5];

int las=

1,tot=1;

inline

void

ins(

int x)

} las=p;}}

int l,cnt[s+5]

,cur,tag;

ll ans;

intmain()

for(

;l < i - len+1;

++l)

--cnt[cur ^ tag]

,cur ^=1

<< id[s[l]];

tag ^=1

<< x,cur ^=1

<< x,

++cnt[tag ^(1

<< x)];

for(

int i0=

0;i0 <2;

++i0)

if(yjy[0]

==-1|| yjy[0]

== i0)

for(

int i1=

0;i1 <2;

++i1)

if(yjy[1]

==-1|| yjy[1]

== i1)

for(

int i2=

0;i2 <2;

++i2)

if(yjy[2]

==-1|| yjy[2]

== i2)

for(

int i3=

0;i3 <2;

++i3)

if(yjy[3]

==-1|| yjy[3]

== i3)

ans +

= cnt[

(i0 |

(i1 <<1)

|(i2 <<2)

|(i3 <<3)

)^ tag];}

printf

("%lld\n"

,ans);}

}

物件導向部分 201

小夥伴們,還在為不知道怎麼下手而頭疼嗎,我們程式競賽協會來幫你們啦 啦啦啦。另外,如果有對程式設計含有濃厚興趣的同學,我們隨時歡迎你們的加入喲 策劃 譚兆飛 程式設計 管懷文 協助 一號人員要求給她打碼 乾脆二號也打碼好了o o 其實只是提供了題目啦 物件導向部分 201 include inclu...

2 01揹包問題

有 nn 件物品和乙個容量是 vv 的揹包。每件物品只能使用一次。第 ii 件物品的體積是 vivi,價值是 wiwi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。輸入格式 第一行兩個整數,n,vn,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 n...

2 01揹包問題

有 nn 件物品和乙個容量是 vv 的揹包。每件物品只能使用一次。第 ii 件物品的體積是 vivi,價值是 wiwi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。第一行兩個整數,n,vn,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 nn 行,每...