Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the most important thing is reciting the words.

Now George is working on a word list containing \(N\) words.

He has so poor a memory that it is too hard for him to remember all of the words on the list. But he does find a way to help him to remember. He finds that if a sequence of words has a property that for all pairs of neighboring words, the previous one is a substring of the next one, then the sequence of words is easy to remember.

So he decides to eliminate some words from the word list first to make the list easier for him. Meantime, he doesn't want to miss the important words. He gives each word an importance, which is represented by an integer ranging from \(-1000\) to \(1000\), then he wants to know which words to eliminate to maximize the sum of the importance of remaining words. Negative importance just means that George thought it useless and is a waste of time to recite the word.

Note that although he can eliminate any number of words from the word list, he can never change the order between words. In another word, the order of words appeared on the word list is consistent with the order in the input. In addition, a word may have different meanings, so it can appear on the list more than once, and it may have different importance in each occurrence.

空间限制:32MB

时间限制:15s

考虑倒着来,建出 AC 自动机,考虑倒着来,修改后变成一个询问子树最大值,用线段树维护就可以了。

但是空间32MB?

26<32,把一个字符拆成 5 个01,比如把 'a' 拆成 00000,'b' 拆成 00001,然后空间就变成了 \(5\times 2\times N\)

当然也可以三个 \(3\times 10^5\) 压成 1 个 long long。

线段树也是可以压的,注意到关键点只有 \(2\times 10^4\) 个,所以可以找到离一个点最近的关键点祖先。

能共用的数组就共用,dfs写手写栈。

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5,M=2e4+5;
bool x;
int n,t,m,p[M],e_num,tme,q[N],idx,fil[N],l,r,ans,hd[N],ln[M],fr[N],id[M],w[M],sz[N];
bool tg[N];
long long tr[N][9];
char str[N];
struct edge{
int v,nxt;
}e[N];
bool y;
int qry(int u,int c)
{
if(c%3==0)
return tr[u][c/3]&1048575;
if(c%3==1)
return (tr[u][c/3]>>20)&1048575;
return tr[u][c/3]>>40;
}
void gai(int u,int c,int t)
{
if(c%3==0)
tr[u][c/3]=tr[u][c/3]&1152921504605798400LL|t;
if(c%3==1)
tr[u][c/3]=tr[u][c/3]&1152920405096267775LL|((1LL*t)<<20);
if(c%3==2)
tr[u][c/3]=tr[u][c/3]&1099511627775LL|((1LL*t)<<40LL);
}
void add_edge(int u,int v)
{
e[++e_num]=(edge){v,hd[u]};
hd[u]=e_num;
}
int insert(char s[])
{
int u=0;
for(int i=0,k;s[i];i++)
{
if(!(k=qry(u,s[i]-'a')))
{
gai(u,s[i]-'a',k=++idx);
memset(tr[idx],0,sizeof(tr[idx]));
}
u=k;
}
return u;
}
int cmp(int x,int y)
{
return ln[x]-ln[x-1]>ln[y]-ln[y-1];
}
void upd(int o,int l,int r,int x,int y)
{
if(l==r)
return hd[o]=max(hd[o],y),void();
int md=l+r>>1;
if(md>=x)
upd(o<<1,l,md,x,y);
else
upd(o<<1|1,md+1,r,x,y);
hd[o]=max(hd[o<<1],hd[o<<1|1]);
}
int ask(int o,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
return hd[o];
int md=l+r>>1,ans=0;
if(md>=x)
ans=max(ans,ask(o<<1,l,md,x,y));
if(md<y)
ans=max(ans,ask(o<<1|1,md+1,r,x,y));
return ans;
}
void build()
{
memset(fil,0,sizeof(fil));
l=1,r=0;
for(int i=0,k;i<26;i++)
if(k=qry(0,i))
q[++r]=k;
while(l<=r)
{
for(int i=0,k;i<26;i++)
{
if(k=qry(q[l],i))
fil[q[++r]=k]=qry(fil[q[l]],i);
else
gai(q[l],i,qry(fil[q[l]],i));
}
++l;
}
for(int i=1;i<=idx;i++)
add_edge(fil[i],i);
memset(tg,0,sizeof(tg));
memset(sz,0,sizeof(sz));
for(int i=1;i<=n;i++)
tg[p[i]]=sz[p[i]]=1;
for(int i=1;i<=r;i++)
{
if(sz[q[i]])
fr[q[i]]=q[i];
else
fr[q[i]]=fr[fil[q[i]]];
}
for(int i=r;i;--i)
sz[fil[q[i]]]+=sz[q[i]];
q[l=r=1]=0;
while(r)
{
int x=q[r];
--r;
if(tg[x])
fil[x]=++tme;
for(int i=hd[x];i;i=e[i].nxt)
q[++r]=e[i].v;
}
}
int main()
{
//printf("%d\n",(&y-&x)>>20);
scanf("%d",&t);
for(int T=1;T<=t;T++)
{
memset(tr[0],0,sizeof(tr[0]));
memset(hd,tme=idx=e_num=0,sizeof(hd));
ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s%d",str+ln[i-1],w+i);
p[i]=insert(str+ln[i-1]);
ln[i]=ln[i-1]+strlen(str+ln[i-1]);
}
build();
memset(hd,0,sizeof(hd));
for(int i=n,dp;i;i--)
{
int u=0;
ans=max(ans,dp=w[i]+max(0,ask(1,1,tme,fil[p[i]],fil[p[i]]+sz[p[i]]-1)));
for(int j=ln[i-1];j<ln[i];j++)
{
u=qry(u,str[j]-'a');
if(fil[fr[u]])
upd(1,1,tme,fil[fr[u]],dp);
}
}
printf("Case #%d: %d\n",T,ans);
}
}

[HDU4117] GRE的更多相关文章

  1. HDU4117 GRE WORDS(AC自动机+线段树维护fail树的dfs序)

    Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the mos ...

  2. 【Network】OVS VXLAN/GRE 实践

    参考资料: OVS/VXLAN/GRE参考 ovs vxlan IP overray_百度搜索 OVS操作总结-Neutron-about云开发 OpenStack OVS GRE/VXLAN网络_z ...

  3. 【Network】OVS、VXLAN/GRE、OVN等 实现 Docker/Kubernetes 网络的多租户隔离

    多租户隔离 DragonFlow与OVN | SDNLAB | 专注网络创新技术 Neutron社区每周记(6.25~7.6)| OVS将加入Linux基金会?OVN或抛弃ovsdb? | Unite ...

  4. Neutron 理解 (3): Open vSwitch + GRE/VxLAN 组网 [Netruon Open vSwitch + GRE/VxLAN Virutal Network]

    学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...

  5. GRE与Vxlan网络详解

    1. GRE 1.1 概念 GRE全称是Generic Routing Encapsulation,是一种协议封装的格式,具体格式内容见:https://tools.ietf.org/html/rfc ...

  6. 探索 OpenStack 之(8):Neutron 深入探索之 OVS + GRE 之 完整网络流程 篇

    前两篇博文分别研究了Compute节点和Neutron节点内部的网络架构.本文通过一些典型流程案例来分析具体网络流程过程. 0. 环境 同 学习OpenStack之(7):Neutron 深入学习之 ...

  7. openstack网络(neutron)模式之GRE的基本原理

    neutron网络目的是为OpenStack云更灵活的划分网络,在多租户的环境下提供给每个租户独立的网络环境. neutron混合实施了第二层的VLAN和第三层的路由服务,它可为支持的网络提供防火墙, ...

  8. 探索 OpenStack 之(7):Neutron 深入探索之 Open vSwitch (OVS) + GRE 之 Neutron节点篇

    0. 测试环境 硬件环境:还是使用四节点OpenStack部署环境,参见 http://www.cnblogs.com/sammyliu/p/4190843.html OpenStack配置: ten ...

  9. 学习OpenStack之(6):Neutron 深入学习之 OVS + GRE 之 Compute node 篇

    0.环境 硬件环境见上一篇博客:学习OpenStack之(5):在Mac上部署Juno版本OpenStack 四节点环境 OpenStack网络配置:一个tenant, 2个虚机 Type drive ...

  10. gre网络细节

    一.OpenStack网络设备的命名规律: 1.TenantA的router和Linux网络命名空间qrouter名称 root@controller:~# neutron --os-tenant-n ...

随机推荐

  1. 一个可将执行文件打包成Windows服务的.Net开源工具

    Windows服务一种在后台持续运行的程序,它可以在系统启动时自动启动,并在后台执行特定的任务,例如监视文件系统.管理硬件设备.执行定时任务等. 今天推荐一个可将执行文件打包成Windows 服务的工 ...

  2. Mysql优化篇-索引优化与查询优化

    1.索引失败案列 如果查询时没有使用索引,查询语句就会扫描表中所有记录,在数据量大的情况下,查询会很慢. (1)全值匹配 (2)最佳左前缀法则 mysql可以为多个字段创建索引,一个索引可以包括16个 ...

  3. WPF中的DesignerProperties

    在WPF开发过程中,最容易遇到的一个问题:就是在自定义控件的过程中写好业务逻辑后,在调用的地方,打开.xmal文件设计器时出现异常,经过排查发现是由于自定义控件初始化过程中需要进行赋值操作.为了能够让 ...

  4. MySQL实战实战系列 04 深入浅出索引(下)

    在上一篇文章中,我和你介绍了 InnoDB 索引的数据结构模型,今天我们再继续聊聊跟 MySQL 索引有关的概念. 在开始这篇文章之前,我们先来看一下这个问题: 在下面这个表 T 中,如果我执行 se ...

  5. win如何根据端口号查找并杀死一个线程

    查看端口占用 netstat -ano | findstr "端口号" 杀死一个进程 taskkill /pid 进程号 -f

  6. CCF CSP认证注册、报名、查询成绩、做模拟题等答疑

    CCF CSP认证注册.报名.查询成绩.做模拟题等答疑 CCF CSP认证中心将考生在注册,或报名,或查询成绩,或历次真题练习时遇到的问题进行汇总,并给出解决方法,具体如下: 1.注册时,姓名可否随意 ...

  7. macbook-键盘连击问题002

    https://support.apple.com/zh-cn/HT205662 如何清洁 MacBook 或 MacBook Pro 的键盘 如果您的 MacBook(2015 年及更新机型)或 M ...

  8. [GXYCTF 2019]Ping Ping Ping

    题目就是ping,而且这还有一个查询窗口,就随便查询试试 ping了一下本地,发现没有什么很大的作用,给出了提示是php可以执行系统函数这就感到神奇了,就还是上网搜了搜 发现可以在查询IP后面进行拼接 ...

  9. 详解.NET依赖注入中对象的创建与“销毁”

    在DI容器中注册类型,DI容器就可以帮我们创建类型的实例:如果注册类型实现了IAsyncDisposable或者IDisposable接口,对象销毁时DI容器还会帮我们调用DisposeAsync或D ...

  10. 【干货】前端开发VUE实例

    最近公司招聘前端开发----VUE方向. 技术面试是必不可少的,发现大多数人应该没有掌握其开发技术,今天就大概总结一下 一.准备工作 需要用到VSCODE最新版,nodejs,vue2.0(现在vue ...