题目链接:zoj 3826 Hierarchical Notation
题目大意:
给定一些结构体,结构体有value值和key值一一对应,value可用{}嵌套key和value对。Q次询问,输出每个key值对应的value值。
解题思路:
用递归将key值映射成一个hash值,这个思路个人觉得很像在p(=131)进制下把一个字符当一位,一个字符串当一个p进制的数,因为ASCII码范围在128以内,所以明显hash只不会产生冲突。
用map映射每个key的value起始终止位置,预处理完了查询就很简单了。
然后预处理出所有具体key值(嵌套的之间加 ‘.’ 字符)的hash,map映射出hash的对应子串的左右坐标。
再模拟请求输出。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
const int maxn=500007;
char s[maxn],t[maxn];
int q,mv,cas;
typedef unsigned long long ull;
map <ull,pair<int,int> > mp;
const ull p=131;
void pre (ull hash){
ull tmp=hash;
int left;
while (s[mv]!='}'){
mv++;
if (s[mv]=='}')
return ;
hash=tmp;
while (s[mv]!=':'){
hash=hash*p+s[mv];
mv++;
}
left=++mv;
if (s[mv]=='{')
pre (hash*p+'.');
else
while (s[mv+1]!=','&&s[mv+1]!='}')
mv++;
mp[hash]=make_pair(left,mv);
// cout<<left<<' '<<mv<<' '<<hash<<endl;
mv++;
}
}
void work (){
ull hash;
int len;
cin>>q;
for (int i=1;i<=q;i++){
scanf ("%s",t+1);
len=strlen (t+1);
hash=0;
for (int j=1;j<=len;j++){
hash=hash*p+t[j];
}
// cout<<t<<' '<<hash;
if (mp.count(hash)){
pair<int,int>tmp=mp[hash];
for (int j=tmp.first;j<=tmp.second;j++){
printf ("%c",s[j]);
}
printf ("\n");
}
else
printf("Error!\n");
}
}
int main (){
cin>>cas;
while (cas--){
scanf ("%s",s+1);
mp.clear();
mv=1;
pre (0);
work();
}
}