对大型字符串最无爱了,比赛的时候被坑了。
一开始一直想着去建树,然后在树上完成查找,结果就不了了之了。
看了别人的解题报告,根本不用建树,对每个key,确定其对应值的起点和终点就行了,然后就可以递归扫描一遍完成任务了。为了查找方便,hash一下,就很容易了。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long long ll;
const ull p=131;
char s[500050];
char ss[500050];
map <ull,pii> mp;
int m;
int mv;
void solve(ull u)
{
ull temp=u;
while (s[mv]!='}')
{
mv++;
if (s[mv]=='}')
return ;
u=temp;
while (s[mv]!=':')
{
u=u*p+s[mv];
mv++;
}
int l=++mv;
if (s[mv]=='{')
solve(u*p+'.');
else
while (s[mv+1]!=','&&s[mv+1]!='}')
mv++;
mp[u]=make_pair(l,mv);
mv++;
}
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%s",s+1);
mv=1;
mp.clear();
solve(0);
scanf("%d",&m);
while (m--)
{
scanf("%s",ss+1);
ull u=0;
int len=strlen(ss+1);
for (int i=1;i<=len;i++)
u=u*p+ss[i];
if (mp.count(u))
{
pii cur=mp[u];
for (int i=cur.first;i<=cur.second;i++)
printf("%c",s[i]);
printf("\n");
}
else
printf("Error!\n");
}
}
}