BZOJ4713 迷失的字符串
分析
首先考虑只有一个串时的做法,可以进行背包dp,记\(f(i,j)\)表示从\(i\)的子树中某点出发到\(i\)能否匹配字符串的\(1 \dots j\)位且\(i\)与\(j\)匹配。同时记\(g(i,j)\)表示从\(i\)出发到\(i\)的子树某点中能否匹配字符串的\(j \dots len\)位并且\(i\)与\(j\)匹配。
显然有
g(i,j)=g(i,j)|(g(k,j+1)\&[ch=s_j]),g(i,len+1)=true
\]
(\(k\)为\(i\)的儿子,\(ch\)为当前边上的字符)
把询问串拼接在一起(中间留空以防出错),\(f\)与\(g\)的区间含义改成在当前点所属串的区间含义,在父亲处合并儿子的答案并对最终答案做出贡献。如果存在\(f(i,j)=true\)且\(g(i,j+1)=true\)那么\(j\)点所属串就可以在以\(i\)为子树的字符树中匹配。
用拓扑排序确定计算顺序避免递归爆栈,用bitset优化位运算的转移提高时空效率。最后注意bzoj太慢了,所以可以把长度为1的询问串特判掉来优化常数。
时空复杂度\(O(N \cdot ∑len / 64)\)。
代码
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x){
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;
const int MAXN=30010,MAXM=35010;
struct Edge
{
int nx,to,w;
}E[MAXN<<1];
int head[MAXN],ecnt;
void addedge(int x,int y,int w)
{
E[++ecnt].to=y,E[ecnt].w=w;
E[ecnt].nx=head[x],head[x]=ecnt;
}
bool exist[27]; // character exist
int s[MAXM],t[MAXM]; // string starting and ending point
char st[MAXM]; // buffer
int ch[MAXM],bl[MAXM]; // new combined string,owner of position
bool final[MAXM]; // final answer,sorted by query rank
queue <int> Q;
void dfs(int x,int fa) // topu sort
{
for(int i=head[x];i;i=E[i].nx)
if(E[i].to!=fa)
dfs(E[i].to,x);
Q.push(x);
}
bool vis[MAXN]; // avoid accessing father
bitset<MAXM> pre,suf,f[MAXN],g[MAXN],hav[27],ans,nowpre,nowsuf;
void bfs()
{
while(!Q.empty())
{
int x=Q.front();
Q.pop();
vis[x]=true;
f[x]=pre,g[x]=suf;
for(int i=head[x];i;i=E[i].nx)
{
int y=E[i].to,w=E[i].w;
if(!vis[y]) continue;
nowpre=(f[y]<<1)&hav[w];
nowsuf=(g[y]>>1)&hav[w];
ans=ans|(f[x]&(nowsuf>>1))|(nowpre&(g[x]>>1)); // 避免在同一条链上合并答案
f[x]=f[x]|nowpre,g[x]=g[x]|nowsuf;
}
}
}
int main()
{
freopen("4713.in","r",stdin);
freopen("4713.out","w",stdout);
int n;
read(n);
for(int i=1;i<n;++i)
{
int x,y;
char w[2];
read(x);read(y);
scanf("%s",w);
w[0]-='a'-1;
addedge(x,y,w[0]);
addedge(y,x,w[0]);
exist[int(w[0])]=true;
}
int m;
read(m);
int sum=0;
for(int i=1;i<=m;++i)
{
s[i]=sum; // 两两字符串之间留空以防错。字符串前一位置留空
scanf("%s",st+1);
int l=strlen(st+1);
if(l==1)
{
if(exist[st[1]-'a'+1])
final[i]=true;
continue;
}
for(int j=1;j<=l;++j)
ch[sum+j]=st[j]-'a'+1;
t[i]=sum+l+1;
for(int j=s[i];j<t[i];++j)
bl[j]=i;
sum=sum+l+1;
}
for(int i=1;i<=m;++i)
{ // 给f,g初始化
pre.set(s[i]);
suf.set(t[i]);
}
for(int i=0;i<=sum;++i)
hav[ch[i]].set(i); // f,g转移用
dfs(1,0);
bfs();
for(int i=0;i<=sum;++i)
if(ans[i])
final[bl[i]]=true;
for(int i=1;i<=m;++i)
if(final[i])
puts("YES");
else
puts("NO");
// fclose(stdin);
// fclose(stdout);
return 0;
}
BZOJ4713 迷失的字符串的更多相关文章
- BZOJ4713 迷失的字符串 解题报告
BZOJ4713 题目大意:有 \(n\) 个点 \(n-1\) 条边,每条边有一个字符.给你 \(m\) 个字符串 \(s_i\),问每个字符串是否可以通过树上的一条简单路径表示. \(n,m\le ...
- web config数据库连接字符串加密
ASP.NET web.config中,数据库连接字符串的加密与解密 ASP.NET web.config中,数据库连接字符串的加密与解密. 开始--->运行,输入cmd,接着输入以下内容 加密 ...
- 【CTF REVERSE】ctf02-查找字符串
1.前言 公司大拿给写的一个CTF逆向程序,提升我们组内人员的水平. 基于对话框MFC框架开发,使用EDIT控制特性隐藏Flag,可借助spy4win之类窗体工具找出Flag. 程序加UPX壳,已对壳 ...
- ADO.NET:连接数据字符串
ylbtech-ADO.NET:ADO.NET-Oracle|SQLServer|MySql|Access|Excel-dddd ADO.NET:连接数据字符串 1.A,SqlServer返回顶部 1 ...
- YTU 2802: 判断字符串是否为回文
2802: 判断字符串是否为回文 时间限制: 1 Sec 内存限制: 128 MB 提交: 348 解决: 246 题目描述 编写程序,判断输入的一个字符串是否为回文.若是则输出"Yes ...
- YTU 2420: C语言习题 不等长字符串排序
2420: C语言习题 不等长字符串排序 时间限制: 1 Sec 内存限制: 128 MB 提交: 460 解决: 239 题目描述 在主函数中输入n(n<=10)个不等长的字符串.用另一函 ...
- YTU 2419: C语言习题 等长字符串排序
2419: C语言习题 等长字符串排序 时间限制: 1 Sec 内存限制: 128 MB 提交: 650 解决: 249 题目描述 在主函数中输入n(n<=10)个等长的字符串.用另一函数对 ...
- YTU 2424: C语言习题 字符串比较
2424: C语言习题 字符串比较 时间限制: 1 Sec 内存限制: 128 MB 提交: 1042 解决: 613 题目描述 写一函数,实现两个字符串的比较.即自己写一个strcmp函数,函数 ...
- YTU 2417: C语言习题 字符串长度
2417: C语言习题 字符串长度 时间限制: 1 Sec 内存限制: 128 MB 提交: 758 解决: 548 题目描述 写一函数,求一个字符串的长度.在main函数中输入字符串,并输出其长 ...
随机推荐
- python打印ms
ct打印的是时间戳,时间戳的小数点后前三位为ms eg:1555644362.055328 ms = 055 import time ct = time.time() local_time = ...
- Silverlight自定义控件系列 – TreeView (2) 基本布局和States
TreeView的树形结构都以缩进方式显示,现在来完成这部分. 首先,要定义出每个节点上都包含什么东西.先看看Win7资源管理器的TreeView: 图2.1 资源管理器 一个通用的TreeView至 ...
- Java 本地环境设置
如果你希望在你的本地环境中设置 Java 程序环境,下面的这部分将会指导你在你的本地计算机上下载和设置 Java 环境.你可以按照下面的步骤进行. Java SE 目前是免费下载的,你可以通过单击下面 ...
- H5基础知识(一)
一.概述 HTML5 是html4.0 升级版 结构 Html5 .样式 css3 .行为: API 都有所增强 HTML5并不仅仅只是做为HTML标记语言的一个最新版本,更重要的是它制定了Web ...
- 37. Sudoku Solver *HARD*
Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...
- OC MRC之autorelease问题(代码分析)
// // main.m // 08-autorelease // // Created by apple on 13-8-9. // Copyright (c) 2013年 itcast. All ...
- Apollo配置中心介绍
参考链接:https://github.com/ctripcorp/apollo/wiki/Apollo%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83%E4%BB%8B%E7 ...
- kill prefix out 1 homo,hemero out1
1● homo 同性恋者 2●hetero 异性恋者
- 解密微信sqlite数据库
最近在研究解密微信APP的数据库, 1.通过Android手机内置备份功能,可以获取到微信的数据库文件,再通过adb传到电脑上. 2.获取微信EnMicroMsg.db库的密码(通过IMEI和uin值 ...
- Flask初级(四)flash在模板中使用静态文件
Project name :Flask_Plan templates: 默认设置下,Flask在程序根目录中名为static的子目录中寻找静态文件. 随便找个图片放进去把,命令test.png Fla ...