ac自动机fail树上dfs序建可持久化线段树
2021/5/17 18:25:24
本文主要是介绍ac自动机fail树上dfs序建可持久化线段树,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
#include <cstring> #include <cstdio> #define max(a,b) a>b?a:b const int mn=300005; struct Trie{ int father,fail,next[26]; void init(){ father=fail=0; memset(next,0,sizeof next); } }tree[mn]; struct Xls{ int size,y[mn],nxt[mn],fst[mn]; void set(){ size=0; memset(fst,0,sizeof fst); } void add(int a,int b){ y[++size]=b; nxt[size]=fst[a]; fst[a]=size; } }g; struct Segtree{ int val,add,l,r; }segtree[mn*4]; char str[mn]; int pos[mn],n,cnt,val[21000],in[mn],out[mn]; void build(char ch[]){ int rt=1,t,len=strlen(ch); for (int i=0;i<len;i++){ t=ch[i]-'a'; if (!tree[rt].next[t]){ tree[++cnt].init(); tree[rt].next[t]=cnt; } tree[tree[rt].next[t]].father=rt; rt=tree[rt].next[t]; } } int q[310000]; void build_AC(){ int head=0,tail=0,rt,son,k; q[++tail]=1;tree[0].fail=1; while (head<tail){ rt=q[++head]; for (int i=0;i<26;i++){ son=tree[rt].next[i]; if (!son){ tree[rt].next[i]=tree[tree[rt].fail].next[i]; continue; } k=tree[rt].fail; while (!tree[k].next[i]) k=tree[k].fail; tree[son].fail=tree[k].next[i]; q[++tail]=son; } } g.set(); for (int i=1;i<=cnt;i++) g.add(tree[i].fail,i); } int count_dfs; void dfs(int rt){ in[rt]=++count_dfs; for (int i=g.fst[rt];i;i=g.nxt[i]) dfs(i); out[rt]=count_dfs; } void buildseg(int rt,int le,int ri){ segtree[rt].val=segtree[rt].add=0; segtree[rt].l=le;segtree[rt].r=ri; if (le==ri) return; buildseg(rt<<1,le,(le+ri)>>1); buildseg(rt<<1|1,((le+ri)>>1)+1,ri); } void pushdown(int rt){ if (segtree[rt].add){ segtree[rt<<1].add=max(segtree[rt<<1].add,segtree[rt].add); segtree[rt<<1].val=max(segtree[rt<<1].val,segtree[rt].add); segtree[rt<<1|1].add=max(segtree[rt<<1|1].add,segtree[rt].add); segtree[rt<<1|1].val=max(segtree[rt<<1|1].val,segtree[rt].add); segtree[rt].add=0; } } int query(int rt,int x){ if (segtree[rt].l==segtree[rt].r) return segtree[rt].val; pushdown(rt); if (x<=segtree[rt<<1].r) return query(rt<<1,x); else return query(rt<<1|1,x); } int XLE,XRI,Xval; void update(int rt){ if (segtree[rt].l>XRI||segtree[rt].r<XLE) return; if (XLE<=segtree[rt].l&&segtree[rt].r<=XRI){ segtree[rt].val=max(segtree[rt].val,Xval); segtree[rt].add=max(segtree[rt].add,Xval); return; } pushdown(rt); update(rt<<1); update(rt<<1|1); segtree[rt].val=max(segtree[rt<<1].val,segtree[rt<<1|1].val); } int solve(){ int rt,t,big,result=0; for (int i=1;i<=n;i++){ rt=1;big=0; for (int j=pos[i-1];j<pos[i];j++){ t=str[j]-'a'; rt=tree[rt].next[t]; big=max(big,query(1,in[rt])); } XLE=in[rt];XRI=out[rt];Xval=big+val[i]; update(1); result=max(result,Xval); } return result; } int main(){ int T; scanf("%d",&T); for (int Case=1;Case<=T;Case++){ memset(str,0,sizeof str); memset(pos,0,sizeof pos); cnt=1; tree[0].init(); tree[1].init(); for (int i=0;i<26;i++) tree[0].next[i]=1; scanf("%d",&n); for (int i=1;i<=n;i++){ scanf("%s%d",str+pos[i-1],&val[i]); build(str+pos[i-1]); pos[i]=pos[i-1]+strlen(str+pos[i-1]); } build_AC(); count_dfs=0; dfs(1); buildseg(1,1,count_dfs); printf("Case #%d: %d\n",Case,solve()); } return 0; }
这篇关于ac自动机fail树上dfs序建可持久化线段树的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享