http://acm.hdu.edu.cn/showproblem.php?pid=1298
建两棵字典树 一棵用小写字母建 用来维护所有包括当前前缀的字符串的出现概率之和 另一棵用数字建看当前数字前缀下根据第一棵字典树应该用哪个字母前缀表示
#include <bits/stdc++.h>
using namespace std;
struct node
{
node *next[26];
int sum;
int id;
};
node *root1,*root2;
int p[1010],mp[1010];
int n,q;
char pre[1010][110];
void init()
{
mp['a']=mp['b']=mp['c']=2;
mp['d']=mp['e']=mp['f']=3;
mp['g']=mp['h']=mp['i']=4;
mp['j']=mp['k']=mp['l']=5;
mp['m']=mp['n']=mp['o']=6;
mp['p']=mp['q']=mp['r']=mp['s']=7;
mp['t']=mp['u']=mp['v']=8;
mp['w']=mp['x']=mp['y']=mp['z']=9;
}
void getnode(node *&ptr)
{
int i;
ptr=new node;
for(i=0;i<26;i++) ptr->next[i]=NULL;
ptr->sum=0;
ptr->id=-1;
}
void destruct(node *ptr)
{
int i;
for(i=0;i<26;i++)
{
if(ptr->next[i]!=NULL) destruct(ptr->next[i]);
}
delete ptr;
}
void updateI(node *ptr,char *ch,int val,int cur,int len)
{
if(ptr->next[ch[cur]-'a']==NULL) getnode(ptr->next[ch[cur]-'a']);
ptr->next[ch[cur]-'a']->sum+=val;
if(cur==len-1) return;
updateI(ptr->next[ch[cur]-'a'],ch,val,cur+1,len);
}
void updateII(node *ptr1,node *ptr2,char *ch,int id,int cur,int len)
{
if(ptr2->next[mp[ch[cur]]]==NULL) getnode(ptr2->next[mp[ch[cur]]]);
if(ptr2->next[mp[ch[cur]]]->sum<ptr1->next[ch[cur]-'a']->sum)
{
ptr2->next[mp[ch[cur]]]->sum=ptr1->next[ch[cur]-'a']->sum;
ptr2->next[mp[ch[cur]]]->id=id;
}
if(cur==len-1) return;
updateII(ptr1->next[ch[cur]-'a'],ptr2->next[mp[ch[cur]]],ch,id,cur+1,len);
}
void query(node *ptr,char *ch,int cur,int len)
{
int id,i;
if(ptr->next[ch[cur]-'0']==NULL)
{
for(i=cur;i<len;i++)
{
printf("MANUALLY\n");
}
return;
}
id=ptr->next[ch[cur]-'0']->id;
for(i=0;i<=cur;i++)
{
printf("%c",pre[id][i]);
}
printf("\n");
if(cur==len-1) return;
query(ptr->next[ch[cur]-'0'],ch,cur+1,len);
}
int main()
{
int t,cas,l,i,j;
char tmp[110];
scanf("%d",&t);
init();
for(cas=1;cas<=t;cas++)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s%d",pre[i],&p[i]);
}
getnode(root1);
for(i=0;i<n;i++)
{
updateI(root1,pre[i],p[i],0,strlen(pre[i]));
}
getnode(root2);
for(i=0;i<n;i++)
{
updateII(root1,root2,pre[i],i,0,strlen(pre[i]));
}
printf("Scenario #%d:\n",cas);
scanf("%d",&q);
while(q--)
{
scanf("%s",tmp);
l=strlen(tmp);
query(root2,tmp,0,l-1);
printf("\n");
}
printf("\n");
destruct(root1);
destruct(root2);
}
return 0;
}