[阈值 二进制分组 && AC自动机]HDU4787. GRE Words Revenge
来源:互联网 发布:视频云平台 阿里云 编辑:程序博客网 时间:2024/06/07 06:06
如果不强制在线,那么可以分治,所以想到可以二进制分组。
但是询问总长度是
可以只建两个AC自动机,当其中一个AC自动机的节点数超过某个值的时候,就把这个自动机与另一个合并,这样询问的总复杂度就是线性的,插入复杂度是
#include <cstdio>#include <iostream>#include <algorithm>#include <cmath>#include <cstring>using namespace std;const int N=500010;int T,n,cnt,lst,size;struct NODE{ NODE *c[2],*fail; int val,w; NODE(){ val=w=0; c[0]=c[1]=0; }}a[N],*B,*S;char s[N*10],t[N*10];inline void NEW(NODE *&x){ a[cnt].val=a[cnt].w=0; a[cnt].c[0]=a[cnt].c[1]=0; x=a+cnt; cnt++;}inline void Add(NODE *&rt,char *a,int len){ if(!rt) NEW(rt); NODE *cur=rt; for(int i=1;i<=len;i++){ if(!cur->c[a[i]-'0']) NEW(cur->c[a[i]-'0']); cur=cur->c[a[i]-'0']; } cur->val=1;}NODE *Merge(NODE *&x,NODE *y){ if(!x || !y) return !x?y:x; x->val|=y->val; x->c[0]=Merge(x->c[0],y->c[0]); x->c[1]=Merge(x->c[1],y->c[1]); return x;}NODE *Q[N];int l,r;inline void Build(NODE *x){ l=r=1; Q[1]=x; x->fail=0; x->w=x->val; while(l<=r){ NODE *u=Q[l++]; for(int i=0;i<2;i++){ NODE *v=u->c[i]; if(!v) continue; v->w=v->val; if(u==x) v->fail=0; else{ NODE *p=u->fail; while(p && !p->c[i]) p=p->fail; if(!p) p=x; v->fail=p->c[i]; if(v->fail) v->w+=v->fail->w; } Q[++r]=v; } }}inline int Query(NODE *rt,char *a,int len){ if(!rt) return 0; int ret=0; NODE *cur=rt; for(int i=1;i<=len;i++){ while(cur && !cur->c[a[i]-'0']) cur=cur->fail; if(!cur) cur=rt; if(cur->c[a[i]-'0']) cur=cur->c[a[i]-'0']; ret+=cur->w; } return ret;}inline bool find(NODE *rt,char *a,int len){ if(!rt) return false; NODE *cur=rt; for(int i=1;i<=len;i++){ if(!cur->c[a[i]-'0']) return false; cur=cur->c[a[i]-'0']; } return cur->val;}int main(){ scanf("%d",&T); int CASE=0; while(T--){ printf("Case #%d:\n",++CASE); scanf("%d",&n); B=S=0; lst=size=0; int BK=820; for(int i=1;i<=n;i++){ scanf("%s",s); int len=strlen(s+1); for(int j=1;j<=len;j++) t[j]=s[(j+lst-1)%len+1]; if(*s=='+'){ if(find(B,t,len)) continue; Add(S,t,len),size+=len; if(size>=BK){ B=Merge(B,S); Build(B); S=0; size=0; } else Build(S); } else{ printf("%d\n",lst=Query(S,t,len)+Query(B,t,len)); } } } return 0;}
阅读全文
1 0
- [阈值 二进制分组 && AC自动机]HDU4787. GRE Words Revenge
- [二进制分组+AC自动机] HDU4787 GRE Words Revenge
- 【二进制分组+AC自动机】HDU4787[GRE Words Revenge]题解
- HDU4787--GRE Words Revenge(在线AC自动机)
- 【HDU4787】GRE Words Revenge【AC自动机】【AC自动机合并】
- [ AC自动机 二进制分组/阈值 ] HDU4787
- [二进制分组 AC自动机] HDU 4787 GRE Words Revenge
- hdu4787 GRE Words Revenge,AC自动机,平方分割
- hdu4787 GRE Words Revenge
- HDU 4787 GRE Words Revenge AC自动机
- hdu 4787 GRE Words Revenge(AC自动机)
- hdu 4787 GRE Words Revenge (在线AC自动机)
- hdu 4787 GRE Words Revenge(分块+AC自动机)
- HDU 4787 GRE Words Revenge(在线AC自动机)
- HDU 4787 GRE Words Revenge 在线AC自动机
- hdu 4787 GRE Words Revenge(在线AC自动机)
- HDOJ 题目4787 GRE Words Revenge(在线ac自动机,离线也可做)
- HDU 4787 GRE Words Revenge(在线AC自动机)★ ★
- Java责任链模式
- Python中range()的作用,和我个人的理解
- python 内建函数isinstance的用法以及与type的区别
- 学习python全记录
- 安卓ListView选中后保持高亮状态,且两级联动带图标(升级版)
- [阈值 二进制分组 && AC自动机]HDU4787. GRE Words Revenge
- apue 4.22 读目录代码解析Reading Directories
- 360全景倒车影像2017年最新十大品牌排名
- 阿里云新用户1元建站
- Git使用教程1-安装Git
- Spring cloud微服务实战——高可用注册中心(二)
- bootStrap table 使用
- 三、面向对象(下)
- Android 多线程保证操作同步(同步锁的俩种)