[HDU4117] GRE
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的更多相关文章
- HDU4117 GRE WORDS(AC自动机+线段树维护fail树的dfs序)
Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the mos ...
- 【Network】OVS VXLAN/GRE 实践
参考资料: OVS/VXLAN/GRE参考 ovs vxlan IP overray_百度搜索 OVS操作总结-Neutron-about云开发 OpenStack OVS GRE/VXLAN网络_z ...
- 【Network】OVS、VXLAN/GRE、OVN等 实现 Docker/Kubernetes 网络的多租户隔离
多租户隔离 DragonFlow与OVN | SDNLAB | 专注网络创新技术 Neutron社区每周记(6.25~7.6)| OVS将加入Linux基金会?OVN或抛弃ovsdb? | Unite ...
- Neutron 理解 (3): Open vSwitch + GRE/VxLAN 组网 [Netruon Open vSwitch + GRE/VxLAN Virutal Network]
学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...
- GRE与Vxlan网络详解
1. GRE 1.1 概念 GRE全称是Generic Routing Encapsulation,是一种协议封装的格式,具体格式内容见:https://tools.ietf.org/html/rfc ...
- 探索 OpenStack 之(8):Neutron 深入探索之 OVS + GRE 之 完整网络流程 篇
前两篇博文分别研究了Compute节点和Neutron节点内部的网络架构.本文通过一些典型流程案例来分析具体网络流程过程. 0. 环境 同 学习OpenStack之(7):Neutron 深入学习之 ...
- openstack网络(neutron)模式之GRE的基本原理
neutron网络目的是为OpenStack云更灵活的划分网络,在多租户的环境下提供给每个租户独立的网络环境. neutron混合实施了第二层的VLAN和第三层的路由服务,它可为支持的网络提供防火墙, ...
- 探索 OpenStack 之(7):Neutron 深入探索之 Open vSwitch (OVS) + GRE 之 Neutron节点篇
0. 测试环境 硬件环境:还是使用四节点OpenStack部署环境,参见 http://www.cnblogs.com/sammyliu/p/4190843.html OpenStack配置: ten ...
- 学习OpenStack之(6):Neutron 深入学习之 OVS + GRE 之 Compute node 篇
0.环境 硬件环境见上一篇博客:学习OpenStack之(5):在Mac上部署Juno版本OpenStack 四节点环境 OpenStack网络配置:一个tenant, 2个虚机 Type drive ...
- gre网络细节
一.OpenStack网络设备的命名规律: 1.TenantA的router和Linux网络命名空间qrouter名称 root@controller:~# neutron --os-tenant-n ...
随机推荐
- SRC赏金猎人—笔记一
以下是我如何将 webshell 上传到一个旧目标中, 这是使用谷歌dorks,Js检查和文件上传过滤器绕过. 过程 1.我随机选择了一个范围很大的目标开始 2.我启动了自动化脚本来发现使用的技术.d ...
- 历时数月钻研推流/对比各种流媒体服务程序/PK总结
1 前言 大量测试下来,网页显示视频流实时性从高到低依次是 webrtc > ws-flv > flv > hls.播放器打开rtsp/rtmp视频流实时性由具体的播放器控制,比如缓 ...
- Java - ReentrantLock锁分析
Java - JUC核心类AbstractQueuedSynchronizer(AQS)底层实现 一. AQS内部结构介绍 JUC是Java中一个包 java.util.concurrent . ...
- 拼多多sku详情的获取分析以及应用
一.拼多多sku详情获取方式 要获取拼多多SKU详情,需要使用拼多多的API接口,以下是获取拼多多SKU详情的步骤: 1.注册拼多多开放平台账户并创建应用 拼多多创建开发者账户并创建应用,获得应用ID ...
- API数据接口的应用步骤
API(Application Programming Interface)是现代软件应用程序开发中的一项重要技术,它允许不同的应用程序之间进行通信和数据交换.API接口通过提供统一的访问点,使得应用 ...
- 小白弄明白了 unix 时间戳的转换问题
小白对于将 unix 时间戳转换为日期时间和使用日期时间转换为 unix 时间戳,在项目中见到过很多,每次使用时不是用现有的方法转换就是网上搜索方法. 小白见过各种转换方式觉得moment库很是方便, ...
- 我们能从PEP 703中学到什么
PEP703是未来去除GIL的计划,当然现在提案还在继续修改,但大致方向确定了. 对于实现细节我没啥兴趣多说,挑几个我比较在意的点讲讲. 尽量少依赖原子操作的引用计数 没了GIL之后会出现两个以上的线 ...
- IDEA集成码云gitee
参考链接:https://blog.csdn.net/bing_bg/article/details/106437008 1.下载安装git https://git-scm.com/download ...
- Go语言常用标准库——json、文件操作、template、依赖管理及Go_module使用
文章目录 Go语言之json Marshal函数 Unmarshal函数 Go语言之文件操作 打开和关闭文件 读取文件 file.Read() 基本使用 循环读取 bufio读取文件 ioutil读取 ...
- VS Code代码提示( AcWing算法模板,C++实现)
算法模板提取于AcWing上的代码提示 作者:yxc 链接:https://www.acwing.com/file_system/file/content/whole/index/content/21 ...