Bzoj4237 JSOI2012 玄武密碼

2022-05-04 19:57:34 字數 1388 閱讀 9235

在美麗的玄武湖畔,雞鳴寺邊,雞籠山前,有一塊富饒而秀美的土地,人們喚作進香河。相傳一日,一縷紫氣從天而至,只一瞬間便消失在了進香河中。老人們說,這是玄武神靈將天書藏匿在此。 

很多年後,人們終於在進香河地區發現了帶有玄武密碼的文字。更加神奇的是,這份帶有玄武密碼的文字,與玄武湖南岸台城的結構有微妙的關聯。於是,漫長的破譯工作開始了。 

經過分析,我們可以用東南西北四個方向來描述台城城磚的擺放,不妨用乙個長度為n的序列來描述,序列中的元素分別是『e』,『s』,『w』,『n』,代表了東南西北四向,我們稱之為母串。而神秘的玄武密碼是由四象的圖案描述而成的m段文字。這裡的四象,分別是東之青龍,西之白虎,南之朱雀,北之玄武,對東南西北四向相對應。 

現在,考古工作者遇到了乙個難題。對於每一段文字,其字首在母串上的最大匹配長度是多少呢? 

第一行有兩個整數,n和m,分別表示母串的長度和文字段的個數。 

第二行是乙個長度為n的字串,所有字元都滿足是e,s,w和n中的乙個。 

之後m行,每行有乙個字串,描述了一段帶有玄武密碼的文字。依然滿足,所有字元都滿足是e,s,w和n中的乙個。 

輸出有m行,對應m段文字。 

每一行輸出乙個數,表示這一段文字的字首與母串的最大匹配串長度。 

7 3snnssns

nnss

nnnwsee42

0對於100%的資料,n<=10^7,m<=10^5,每一段文字的長度<=100。

***[傳送門](

## 題解

對所有詢問串建立ac自動機。

然後將母串在ac自動機上跑,每走到乙個點x,從x點出發沿著fail(就不寫p了)指標能到的所有字首都是匹配成功的,暴力向上走,碰到走過的就break,這樣每個點最多隻會被標記一次。

#### 時間複雜度

$ o(n+100m)$

## **

```#include#include#include#include#include#include#includeusing namespace std;

queueq;

const int n=1e7+5;

int ch[n][5],f[n],p[n],bo[n],flag[n],tx[50],len[n],tot=1;

char s[n],st[n];

void insert(char *st,int t) }}

int work(int t)

return 0;

}int main()

for (int i=0; i<4; i++) ch[0][i]=1;

pre();

find(s);

for (int i=1; i<=m; i++) printf("%d\n",work(i));

return 0;

}```

miao~~~

BZOJ 4237 稻草人 分治

分治。1.按y軸排序 2.分治處理 l,mid 和 mid 1,r 計算 l,mid 能對 mid 1,r 部分作出的貢獻 隨便花乙個圖發現上半部分維護y值遞增的單調棧下半部分維護y單調減得單調棧,這樣下半部分棧中元素都是可以和上半部分配對不會出現包括的情況,但是x座標必須大於s1 t1 1 就是第...

BZOJ4237 稻草人 題解

我們考慮分治一下 按 x 座標排序 然後對於每一段的兩部分都按 y 排序 左右兩邊都維護乙個單調棧 然後考慮右邊對左邊的貢獻就行了 include define int long long using namespace std const int maxn 2e5 5 int n struct n...

bzoj4237 稻草人 分治

題目 分治 先把所有點按 y 排序,然後二分遞迴 對於每個 mid 計算經過它的矩形的個數,把上面的每個點當做右上角,考慮下面多少點可以作為左下角 上面的限制只有前面的 y 大於等於自己的 y,所以維護遞增的單調棧 下面的限制是後面的 y 小於等於自己的 y,所以維護遞減的單調棧 還要注意 x 的限...