POJ2778 AC自動機 非遞迴的矩陣乘法

2021-06-01 11:17:34 字數 2344 閱讀 2208

回想還是半個月前...跟著matrix67的那文章做矩陣乘法....做到這題就卡住了...決心突破..這兩周從trie入門開始..到今天終於把這題給ac了...雖然這半個月做題量相比以前大大減少....但真正能初步掌握一種演算法還是值得的...

首先這道題我是參考了幾個解題報告的:

如果需要具體思路請先看前面兩篇..特別是後面乙個題解很詳細..並且**很整潔...可以看出很多東西....

我就說下我做這題時出現的問題以及要注意的地方...

1、 ***a表示長度為4末位為a前三位任意但其不能是任意病毒的字首..****代表長度為4每位都任意但其不能是任意病毒的字首

2、 built_ac_automation時word標記需要逆向的傳遞...

3、 built_ac_automation時某個點沒有哪個孩子不需要任何處理..而我開始是按poj3691的方式處理的...

4、 built_matrix時問題很多...這個矩陣的意義是各個字首相互到達方案數...表示每個字首新增乙個字元能轉化到另乙個字首的方案數..

5、 built_matrix時...注意什麼時候要對0點更新..也就是要找的點在其以及其當其不斷向上fail是都沒有這個孩子...就要更新矩陣的0列...但如果這個過程中有某個點其孩子有但是其孩子是病毒點..那也不能更新矩陣的0列..應該不做任何操作..

6、 built_matrix時...若在其或者其向上fail的某個點的孩子找到了能更新的點...那在++後就不要繼續向上fail了...因為繼續往上在找到的實際上還是最先找到的那個..會重複的加..

7、 矩陣乘法時不能用遞迴...遞迴會爆記憶體..所以只能將其拆分成二階乘數的和..

8 、切記!!矩陣裡每個單元要是long long的...因為10^5 * 10^5會爆int !!

好久沒寫這麼長的**了...特別是非模擬題..懷疑這是我非模擬題寫的最長的..比網路流的還長...ps: 我構造矩陣時就先將沒用的點給去了..也就是病毒點..p就是有用點的從0到p.

program: 

#include#include#include#includeusing namespace std; 

struct pp

h,_2m[32];

struct node

a[201];

int m,n,i,g,len,p,point[105];

long long ans;

char s[15];

queuemyqueue;

int turn(char c)

void built_trie(int h,int t)

if (!a[h].s[k])

built_trie(a[h].s[k],t+1);

}int updatefail(int h,int k)

void built_ac_automation()

}return;

}void built_matrix()

else goto a; // 總之進來了就要跳出了...找到了不要繼續fail了..找到了是個病毒也不能繼續fail了..

}if (!kk) break; // 所以在這裡判斷跳出迴圈

kk=a[kk].fail;

} if (f) h.s[k][0]++;

a: ;}}

} pp mul(pp a,pp b)

pp getanswer(int n)

// 得到每個2^k矩陣的值..因為n的範圍小於2^31所以做30個足矣

memset(ans.s,0,sizeof(ans.s));

for (j=0;j<=p;j++) ans.s[j][j]=1;

while (n)

ans=mul(ans,_2m[i]);

n-=m;

}return ans;

}int main()

built_ac_automation();

//------ 去掉病毒點..記錄構造矩陣時的有效點..

p=0; point[0]=0; a[0].w=0;

for (i=1;i<=g;i++)

if (!a[i].word)

//------ 去掉病毒點..記錄構造矩陣時的有效點..

memset(h.s,0,sizeof(h.s));

built_matrix();

h=getanswer(n);

ans=0;

for (i=0;i<=p;i++) ans+=h.s[0][i];

printf("%i64d\n",ans%100000);

return 0;

}

poj2778 ac自動機 矩陣快速冪

poj2778 求長度為m且不包含n個子串的種類數.參考自這個部落格.ac自動機 矩陣快速冪.這兒有個結論.給定乙個有向圖,問從a點恰好走k步 允許重複經過邊 到達b點的方案數mod p的值 把給定的圖轉為鄰接矩陣,即a i,j 1當且僅當存在一條邊i j。令c a a,那麼c i,j a i,k ...

poj2778 ac自動機 矩陣快速冪

給m個子串,求長度為n的不包含子串的母串數,最直接的應該是暴搜,肯定tle,考慮用ac自動機 將子串建成字典樹,通過next表來構造矩陣,然後用矩陣快速冪求長度為n的數量 鄰接矩陣 對於a i,j k 是指從i到j經過k個點的所有情況數 注意對於end陣列,如果某個節點如果fail指標end陣列為1...

poj2778(AC自動機 矩陣快速冪)

題意 給你n個字串,問你長度為m的字串且字串中不含有那n個子串的字串的數量 解題思路 這道題一開始就不太懂,還以為是組合數學的題目,後面看了別人的部落格,才知道這是屬於ac自動機的另一種用法,是關於fail陣列的運用,因為題目問的是不允許包含那n個字串,所以我們可以這麼想,假設乙個trie樹每個結點...