题目绝对够水,我就不详细说明了。
直接上代码吧。只是提示一下要用 unsigned long long。
(不知道我不用字典树为什么会超时,肿么搞的)
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 2300
#define ll unsigned long long
using namespace std;
ll tag[50050],next[50050][60],N;
char s[maxn];
ll g[maxn],dis,tot,now;
ll b,v,k,n;
ll f[maxn];
ll getcode(char cc)
{
if (cc>='a' && cc<='z') return cc-'a';
return cc-'A'+26;
}
void insert(ll x)
{
ll cur=0,tep;
for (ll i=0; s[i]; i++)
{
tep=getcode(s[i]);
if (!next[cur][tep]) next[cur][tep]=++N;
cur=next[cur][tep];
}
tag[cur]=x;
}
ll find()
{
ll cur=0,tep;
for (ll i=0; s[i]; i++)
{
tep=getcode(s[i]);
if (next[cur][tep]==0) return 0;
cur=next[cur][tep];
}
return tag[cur];
}
ll count()
{
ll ans=0;
for (ll i=0; s[i]; i++)
{
ans<<=1;
if (s[i]=='1') ans++;
}
return ans;
}
int main()
{
while (scanf("%llu%llu",&b,&v)!=EOF)
{
dis=(1<<b);
N=0; tot=0;
memset(next,0,sizeof next);
memset(tag,0,sizeof tag);
memset(f,0,sizeof f);
memset(g,0,sizeof g);
for (ll i=1; i<=v; i++)
{
scanf("%s",s);
insert(i);
scanf("%llu",&g[i]);
tot+=g[i];
}
now=1;
for (ll i=1; i<=tot; i++)
{
scanf("%s",s);
k=count();
while (g[now]==0) now++;
g[now]--;
f[now]=f[now]*dis+k;
}
scanf("%llu",&n);
while (n--)
{
scanf("%s",s);
k=find();
printf("%s=",s);
if (k) printf("%llu",f[k]);
printf("
");
}
}
return 0;
}