BZOJ2434 NOI2011 阿狸的打字機

2021-07-09 21:17:56 字數 1479 閱讀 5207

發現一種新的思路,以前從來沒有見過的,即ac自動機的fail樹。

這一題我們先考慮暴力,從root往y的最後乙個點走,如果走到了x的末點,ans++,如果通過fail指標走到了x的末點,ans++。

反過來考慮,從x的末點開始,如果當前點在y串或者通過反向的fail到了y串,ans++。

又發把fail反向之後得到的是一棵樹,那麼也就是要求在x末點的子樹裡有多少個y點,轉化為dfs序後用樹狀陣列維護即可。

#include

#include

#include

#include

#include

#include

#include

#define x first

#define y second

#define ll long long

#define mp make_pair

#define lowbit(x) (x&(-x))

#define debug(...) fprintf(stderr,__va_args__)

using

namespace

std;

const

int maxn=1e5+10;

char s[maxn];

int n;

int first[maxn],e=0,next[maxn],to[maxn],sum[maxn*3],ans[maxn];

void add(int a,int b)

void _add(int x,int d)

}int query(int x)

return res;

}struct acm

int idx(char c)

void insert(char* s)

else

u=son[u][x];

}else

if(s[i]=='p')

val[++k]=u;

else

if(s[i]=='b')

u=fa[u];}}

void getfail()

}while(!q.empty())}}

void add(int a,int b)

void buildtree()

while(!q.empty())

}memset(l,0,sizeof(l));

memset(r,0,sizeof(r));

}void dfs(int u)

r[u]=++dfs_clock;

}void solve()

else

if(s[i]=='p')

}else}}

}ac;

int main()

ac.solve();

for(int i=1;i<=n;i++)

printf("%d\n",ans[i]);

}

bzoj2434 Noi2011 阿狸的打字機

傳送門 description 阿狸喜歡收藏各種稀奇古怪的東西,最近他淘到一台老式的打字機。打字機上只有28個按鍵,分別印有26個小寫英文本母和 b p 兩個字母。經阿狸研究發現,這個打字機是這樣工作的 l 輸入小寫字母,打字機的乙個凹槽中會加入這個字母 這個字母加在凹槽的最後 l 按一下印有 b ...

bzoj 2434 Noi2011 阿狸的打字機

time limit 10 sec memory limit 256 mb submit 3139 solved 1731 submit status discuss 阿狸喜歡收藏各種稀奇古怪的東西,最近他淘到一台老式的打字機。打字機上只有28個按鍵,分別印有26個小寫英文本母和 b p 兩個字母。...

BZOJ2434 NOI2011 阿狸的打字機

bzoj 洛谷我們先想一下最暴力是怎麼搞的 把 ac 自動機建好,每乙個節點,從 y 串的結尾節點往上跳它的父親,和普通的 ac 自動機一樣跳就好了 然而這個可以優化一下 我們將所有詢問離線 每個串統計一次其他串對它的貢獻 就可以有 70pts 了 70pts include include inc...