【問題描述】

呂弗·普自小從英國長大,受到騎士精神的影響,呂弗·普的夢想便是成為一位劫富濟貧的騎士。

呂弗·普拿到了一份全國富豪的名單(不在名單上的都是窮人),上面寫著所有富豪的名字以及他們的總資產,比如豪特斯·珀去年資產有86E,呂弗·普就會準備搶來資助貧困的伯恩兄弟……

現在呂弗·普做了M次打劫計劃,每次要打劫若干個人,他想知道每次能打劫到的總資產是多少

【輸入格式】

第一行一個正整數N,代表富豪的個數

接下來N行,每行一個由小寫字母組成的字串Si和一個非負整數Wi,分別代表第i個富豪的名字和第i個富豪的資產數量

然後一個正整數M,代表呂弗·普的打劫次數

接下來M行,每行第一個數為正整數Xi,代表這次要打劫Xi個人,接下來有X個字串,說明了這Xi個人是誰

【輸出格式】

對於每次打劫任務,輸出一行一個整數表示打劫到的總資產

如果這次打劫任務中打劫了一個窮人,那就輸出-1

【樣例輸入】

2

a 10

b 20

3

2 a b

1 b

2 a c

【樣例輸出】

30

20

-1

【資料範圍與約定】

對於30%
的資料,輸入中每個名字的長度均為1

對於60%
的資料,N,∑Xi<=
100,輸入中每個名字的長度<=10

對於100%的資料,N,∑Xi<=
10^5,輸入中所有名字的總長度<=2*10^6,Wi<=10^9,保證任意兩個富豪名字不同,但不保證打劫計劃中會不會有重複的人

字典樹裸題

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lol;
int tot=;
char s[];
int ch[][],n,m;
lol w[],ans;
void add(lol d)
{int i;
int l=strlen(s);
int now=;
for (i=;i<l;i++)
{
int x=s[i]-'a';
if (!ch[now][x])
{
ch[now][x]=++tot;
w[tot]=-;
}
now=ch[now][x];
}
w[now]=d;
}
lol find()
{int i;
int l=strlen(s);
int now=;
for (i=;i<l;i++)
{
int x=s[i]-'a';
now=ch[now][x];
}
return w[now];
}
int main()
{lol d,k,x;
int i,j;
cin>>n;
w[]=-;
for (i=;i<=n;i++)
{
scanf("%s%lld",s,&d);
add(d);
}
cin>>m;
for (i=;i<=m;i++)
{
scanf("%lld",&k);
bool flag=;
ans=;
for (j=;j<=k;j++)
{
scanf("%s",s);
x=find();
if (x==-)
{
flag=;
break;
}
else ans+=x;
}
if (flag) printf("%lld\n",ans);
else printf("-1\n");
}
}