AC自动机fail树上dfs序建线段树+动态memset清空
题意:http://acm.hdu.edu.cn/showproblem.php?pid=4117
思路:https://blog.csdn.net/u013306830/article/details/77586562
主要就是卡你内存,AC自动机的字典树得要用了再清空。
代码有点长吧。。。
- #include <cstdio>//sprintf islower isupper
- #include <iostream>//pair
- #include <string.h>//strstr substr strcat
- #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
- using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
- #define mem(a,b) memset(a,b,sizeof(a))
- #define pr printf
- #define sc scanf
- #define ls rt<<1
- #define rs rt<<1|1
- const int N=3e5+;
- char s[N];
- int pos[],val[];
- //-------------------------------
- class mymap
- {
- public:
- int tot;
- int head[N];
- int SZ[N];
- int dfn[N],cnt;
- struct
- {
- int to,next;
- }edge[N];
- void Init(int n)
- {
- tot=;
- cnt=-;
- for(int i=;i<=n;++i)
- head[i]=SZ[i]=;
- }
- void add(int from,int to)
- {
- ++tot;
- edge[tot].to=to;
- edge[tot].next=head[from];
- head[from]=tot;
- }
- int dfs(int u)
- {
- ++cnt;
- dfn[u]=cnt;
- SZ[dfn[u]]=;
- for(int i=head[u];i;i=edge[i].next)
- {
- // cout<<edge[i].first<<endl;
- SZ[dfn[u]]+=dfs(edge[i].to);
- }
- return SZ[dfn[u]];
- }
- }TREE;
- class seg_tree
- {
- public:
- int max_[N<<],add[N<<];
- void up(int rt)
- {
- max_[rt]=max(max_[ls],max_[rs]);
- }
- void dn(int rt)
- {
- if(add[rt])
- {
- add[ls]=max(add[ls],add[rt]);
- add[rs]=max(add[rs],add[rt]);
- max_[ls]=max(max_[ls],add[rt]);
- max_[rs]=max(max_[rs],add[rt]);
- add[rt]=;
- }
- }
- void Build(int l,int r,int rt)
- {
- max_[rt]=;
- add[rt]=;
- if(l==r)
- {
- return;
- }
- int mid=(l+r)>>;
- Build(l,mid,rt<<);
- Build(mid+,r,rt<<|);
- }
- int Q_dot(int pos,int l,int r,int rt)
- {
- if(l==r)
- {
- return max_[rt];
- }
- int mid=(l+r)>>;
- dn(rt);
- if(pos<=mid)
- return Q_dot(pos,l,mid,rt<<);
- else
- return Q_dot(pos,mid+,r,rt<<|);
- }
- void update_qu(int L,int R,int V,int l,int r,int rt)
- {
- if(L>R)return;
- if(L<=l&&r<=R)
- {
- max_[rt]=max(max_[rt],V);
- add[rt]=max(add[rt],V);
- return;
- }
- int mid=(l+r)>>;
- dn(rt);
- if(L<=mid)
- update_qu(L,R,V,l,mid,rt<<);
- if(R>mid)
- update_qu(L,R,V,mid+,r,rt<<|);
- up(rt);
- }
- }SEG;
- class ac_automaton
- {
- public:
- int tot;
- int trie[N][];
- int fail[N];
- //other
- //--------------
- void Insert(int l,int r)
- {
- int rt=;
- for(int i=l;i<=r;++i)
- {
- int id=s[i]-'a'+;
- if(!trie[rt][id])
- {
- mem(trie[++tot],);
- trie[rt][id]=tot;
- }
- rt=trie[rt][id];
- }
- }
- queue<int>q;
- void Getfail()
- {
- for(int i=;i<=;++i)
- {
- int id=trie[][i];
- if(id)
- {
- fail[id]=;
- q.push(id);
- }
- }
- while(!q.empty())
- {
- int rt=q.front();q.pop();
- for(int i=;i<=;++i)
- {
- int id=trie[rt][i];
- if(id)
- {
- fail[id]=trie[fail[rt]][i];
- q.push(id);
- }
- else
- trie[rt][i]=trie[fail[rt]][i];
- }
- }
- }
- int Find(int l,int r,int id,int n)
- {
- int rt=;
- int pos=;
- int temp_max=;
- for(int i=l;i<=r;++i)
- {
- rt=trie[rt][s[i]-'a'+];
- pos=TREE.dfn[rt];
- int temp_val=SEG.Q_dot(pos,,n,)+val[id];
- temp_max=max(temp_max,temp_val);
- }
- SEG.update_qu(pos,pos+TREE.SZ[pos]-,temp_max,,n,);
- // for(int j=1;j<=n;++j)pr("%d ",SEG.Q_dot(j,1,n,1));
- // cout<<endl<<"----------------------------------"<<endl;
- return temp_max;
- }
- }AC;
- void solve()
- {
- AC.tot=;
- mem(AC.trie[],);
- int n,tot;
- sc("%d",&n);
- pos[]=;
- for(int i=;i<=n;++i)
- {
- sc("%s %d",s+pos[i],&val[i]);
- int l=strlen(s+pos[i]);
- AC.Insert(pos[i],pos[i]+l-);
- pos[i+]=pos[i]+l;
- }
- tot=AC.tot;
- // pr("%s\n",s+1);
- AC.Getfail();
- TREE.Init(tot);
- SEG.Build(,tot,);
- for(int i=;i<=AC.tot;++i)
- TREE.add(AC.fail[i],i);
- TREE.SZ[]=TREE.dfs();
- int ans=;
- for(int i=;i<=n;++i)
- ans=max(ans,AC.Find(pos[i],pos[i+]-,i,tot));
- pr("%d\n",ans);
- }
- int main()
- {
- int T,cnt=;
- sc("%d",&T);
- while(T--)
- {
- pr("Case #%d: ",++cnt);
- solve();
- }
- return ;
- }
- /**************************************************************************************/
AC自动机fail树上dfs序建线段树+动态memset清空的更多相关文章
- CodeForces - 1207G :Indie Album(AC自动机 fail树上DFS)
题意:有N个串,给出的形式是拼接给出,对于第i行: (1,c)表示字符串i是单个字母c: (2,p,c)表示字符串i=在字符串p后面接上一个字母c. 然后给出M个提问,形式是(i,string).问 ...
- bzoj3306: 树(dfs序+倍增+线段树)
比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...
- URAL 1890 . Money out of Thin Air (dfs序hash + 线段树)
题目链接: URAL 1890 . Money out of Thin Air 题目描述: 给出一个公司里面上司和下级的附属关系,还有每一个人的工资,然后有两种询问: 1:employee x y z ...
- ac自动机fail树上按询问建立上跳指针——cf963D
解法看着吓人,其实就是为了优化ac自动机上暴力跳fail指针.. 另外这题对于复杂度的分析很有学习价值 /* 给定一个母串s,再给定n个询问(k,m) 对于每个询问,求出长度最小的t,使t是s的子串, ...
- 7月13日考试 题解(DFS序+期望+线段树优化建图)
T1 sign 题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和.N<=10000 水题.考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多 ...
- bzoj2819 DFS序 + LCA + 线段树
https://www.lydsy.com/JudgeOnline/problem.php?id=2819 题意:树上单点修改及区间异或和查询. 思维难度不高,但是题比较硬核. 整体思路是维护每一个结 ...
- hdu 3974 Assign the task(dfs序上线段树)
Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...
- Codeforces 877E - Danil and a Part-time Job(dfs序+线段树)
877E - Danil and a Part-time Job 思路:dfs序+线段树 dfs序:http://blog.csdn.net/qq_24489717/article/details/5 ...
- 用dfs序处理线段树的好题吗?
https://www.cnblogs.com/mountaink/p/9878918.html 分析:每次的选取必须选最优的一条链,那我们考虑一下选择这条链后,把这条路上的点的权值更新掉,再采取选最 ...
随机推荐
- java 构造方法中super()和this()
1)super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 2)this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句) 3)super: 它引用当前对 ...
- csp-s模拟90
T1: 每格的不透明度相当与一个边权,转化为从起点到终点所有路径的最大值.实现最长路,最好用$dijk$. T2: 对于$N=100$,$M=8$,考虑状压$dp$.要用一种状态表示某一行的矩形覆盖情 ...
- Python 上下文管理器模块--contextlib
在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...
- ubuntu18.04 systemctl
systemd 是 Linux 下的一款系统和服务管理器,兼容 SysV 和 LSB 的启动脚本.systemd 的特性有:支持并行化任务:同一时候採用 socket 式与 D-Bus 总线式激活服务 ...
- arcgis python 列出一个表所有字段
import arcpy inFeature = arcpy.GetParameterAsText(0) #原始数据 try: fieldList = arcpy.ListFields(inFeatu ...
- JS模拟Touch事件
var ele = document.getElementsByClassName('target_node_class')[0] //may have x and y properties in s ...
- shell cat 用法
cat命令的用途是连接文件或标准输入并打印. 1.命令格式:cat [选项] [文件]... 2.命令功能:cat主要有三大功能:1.一次显示整个文件:cat filename --常用来显示文件 ...
- 安装RabbitMQ管理插件失败
运行 rabbitmq-plugins.bat enable rabbitmq_management后提示失败信息 是因为erlang和RabbitMQ版本冲突导致
- SqlServer2008数据库的备份与还原
1.先是备份数据 1.1.登录sql server management studio 1.2.选中需要备份数据库,右击鼠标,如下图: 1.3.点击备份之后,如下图; 2.数据还原准备 ps: 在开始 ...
- Server 2012使用Windows PowerShell cmdlet安装角色和角色服务功能
Server 2012使用Windows PowerShell cmdlet安装角色和角色服务功能 Windows Server 2012 安装 SQL server 2008 出现了如下错误: 解 ...