分析

$f(i,j)=f(i,j)|(f(k,j−1)\&[ch=s_j]),f(i,0)=true\\ g(i,j)=g(i,j)|(g(k,j+1)\&[ch=s_j]),g(i,len+1)=true$

($k$$i$的儿子,$ch$为当前边上的字符)

代码

#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;
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];

{
E[++ecnt].to=y,E[ecnt].w=w;
}

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
{
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;
{
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;
for(int i=1;i<n;++i)
{
int x,y;
char w[2];
scanf("%s",w);
w[0]-='a'-1;
exist[int(w[0])]=true;
}
int 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;
}



posted on 2018-08-27 11:14  autoint  阅读(283)  评论(0编辑  收藏